private void OnReceiveMessage(Object sender, TcpSocketReceiveEventArgs e) { lock (_connections) { Connection connection; if (!_connections.TryGetValue(e.Socket.ChannelId, out connection)) { throw new InvalidOperationException(); } e.Stream.ProtocolVersion = connection.ProtocolVersion; Caller.Value = connection; Deserializer.Receive(e.Stream, _implementation); Caller.Value = null; } }
/// <summary> /// This method gets called for the first received message, which is the /// handshake. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> /// <remarks> /// Once the handshake is received and accepted, the onReceive event is /// re-bound to ServiceBase::onReceive. /// </remarks> private void OnReceiveHandshake(Object sender, TcpSocketReceiveEventArgs e) { try { uint protocolVersion; ulong hostGuid; ulong serviceGuid; uint serviceUid; ulong interfaceUids; e.Stream.ProtocolVersion = 1; e.Stream.Read(out protocolVersion); e.Stream.Read(out hostGuid); e.Stream.Read(out serviceGuid); e.Stream.Read(out serviceUid); e.Stream.Read(out interfaceUids); if (ServiceUid != serviceUid) { throw new InvalidDataException("The service's Uid do not match."); } if (InterfaceUids != (interfaceUids << 32 | interfaceUids >> 32)) { throw new InvalidDataException("The service interfaces' Uids do not match."); } var connection = new Connection(this, e.Socket); connection.ProtocolVersion = protocolVersion; connection.HostGuid = hostGuid; connection.ServiceGuid = serviceGuid; connection.ServiceUid = serviceUid; connection.InterfaceUids = interfaceUids; e.Socket.MessageReceived -= OnReceiveHandshake; e.Socket.MessageReceived += OnReceiveMessage; if (IsProvider) { SendHandshake(e.Socket); } lock (_connections) { _connections.Add(e.Socket.ChannelId, connection); ++_connectedServicesCount; lock (Sockets) { Sockets.Add(e.Socket); } var connectedRemoteService = ConnectedRemoteService; if (connectedRemoteService != null) { connectedRemoteService(this, new ConnectedRemoteServiceArgs( connection.HostGuid, connection.ServiceGuid, connection.ServiceTag, connection.Socket.RemoteEndPoint)); } } } catch { e.Socket.Close(); } }