Funktionierender Prototyp des Serious Games zur Vermittlung von Wissen zu Software-Engineering-Arbeitsmodellen.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

connect.py 3.8KB

1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. # Implements _both_ a connectable client, and a connectable server.
  2. #
  3. # Note that we cheat just a little - the Server in this demo is not created
  4. # via Normal COM - this means we can avoid registering the server.
  5. # However, the server _is_ accessed as a COM object - just the creation
  6. # is cheated on - so this is still working as a fully-fledged server.
  7. import pythoncom
  8. import win32com.server.connect
  9. import win32com.server.util
  10. from pywin32_testutil import str2bytes
  11. from win32com.server.exception import Exception
  12. # This is the IID of the Events interface both Client and Server support.
  13. IID_IConnectDemoEvents = pythoncom.MakeIID("{A4988850-49C3-11d0-AE5D-52342E000000}")
  14. # The server which implements
  15. # Create a connectable class, that has a single public method
  16. # 'DoIt', which echos to a single sink 'DoneIt'
  17. class ConnectableServer(win32com.server.connect.ConnectableServer):
  18. _public_methods_ = [
  19. "DoIt"
  20. ] + win32com.server.connect.ConnectableServer._public_methods_
  21. _connect_interfaces_ = [IID_IConnectDemoEvents]
  22. # The single public method that the client can call on us
  23. # (ie, as a normal COM server, this exposes just this single method.
  24. def DoIt(self, arg):
  25. # Simply broadcast a notification.
  26. self._BroadcastNotify(self.NotifyDoneIt, (arg,))
  27. def NotifyDoneIt(self, interface, arg):
  28. interface.Invoke(1000, 0, pythoncom.DISPATCH_METHOD, 1, arg)
  29. # Here is the client side of the connection world.
  30. # Define a COM object which implements the methods defined by the
  31. # IConnectDemoEvents interface.
  32. class ConnectableClient:
  33. # This is another cheat - I _know_ the server defines the "DoneIt" event
  34. # as DISPID==1000 - I also know from the implementation details of COM
  35. # that the first method in _public_methods_ gets 1000.
  36. # Normally some explicit DISPID->Method mapping is required.
  37. _public_methods_ = ["OnDoneIt"]
  38. def __init__(self):
  39. self.last_event_arg = None
  40. # A client must implement QI, and respond to a query for the Event interface.
  41. # In addition, it must provide a COM object (which server.util.wrap) does.
  42. def _query_interface_(self, iid):
  43. import win32com.server.util
  44. # Note that this seems like a necessary hack. I am responding to IID_IConnectDemoEvents
  45. # but only creating an IDispatch gateway object.
  46. if iid == IID_IConnectDemoEvents:
  47. return win32com.server.util.wrap(self)
  48. # And here is our event method which gets called.
  49. def OnDoneIt(self, arg):
  50. self.last_event_arg = arg
  51. def CheckEvent(server, client, val, verbose):
  52. client.last_event_arg = None
  53. server.DoIt(val)
  54. if client.last_event_arg != val:
  55. raise RuntimeError("Sent %r, but got back %r" % (val, client.last_event_arg))
  56. if verbose:
  57. print("Sent and received %r" % val)
  58. # A simple test script for all this.
  59. # In the real world, it is likely that the code controlling the server
  60. # will be in the same class as that getting the notifications.
  61. def test(verbose=0):
  62. import win32com.client.connect
  63. import win32com.client.dynamic
  64. import win32com.server.policy
  65. server = win32com.client.dynamic.Dispatch(
  66. win32com.server.util.wrap(ConnectableServer())
  67. )
  68. connection = win32com.client.connect.SimpleConnection()
  69. client = ConnectableClient()
  70. connection.Connect(server, client, IID_IConnectDemoEvents)
  71. CheckEvent(server, client, "Hello", verbose)
  72. CheckEvent(server, client, str2bytes("Here is a null>\x00<"), verbose)
  73. CheckEvent(server, client, "Here is a null>\x00<", verbose)
  74. val = "test-\xe0\xf2" # 2 extended characters.
  75. CheckEvent(server, client, val, verbose)
  76. if verbose:
  77. print("Everything seemed to work!")
  78. # Aggressive memory leak checking (ie, do nothing!) :-) All should cleanup OK???
  79. if __name__ == "__main__":
  80. test(1)