Пример #1
0
        static void ClientDisconnected(object sender, EventArgs e)
        {
            Debug.WriteLine(DateTime.Now + ": Client disconnect: " + ((IClientChannel)sender).SessionId.ToString());
            // cleanup event
            TEventEntry channelEvent;

            if (Lookups.channelToEvent.TryGetValue(sender, out channelEvent))
            {
                // decode session part of event name
                var sessionEventName = channelEvent.eventName.Substring(0, channelEvent.eventName.LastIndexOf('.'));
                var connection       = channelEvent.connection;
                // signal client is removed
                channelEvent.signalIntString(TEventEntry.actionDelete, ((IClientChannel)sender).SessionId); // channel, action delete (optional session id)
                // remove link between channel and event
                channelEvent.unPublish();
                channelEvent.unSubscribe();
                channelEvent.Tag = null;
                Lookups.channelToEvent.Remove(sender);
                //Lookups.channelToClientType.Remove(sender);
                //Lookups.channelToRemoteAddress.Remove(sender);

                lock (Lookups.rootEvent)
                {
                    // check if last channel on session then session can be discarded
                    if (Lookups.checkForLastChannel(sessionEventName + "."))
                    {
                        var sessionEvent = connection.publish(sessionEventName, false); // already published so is just a lookup
                        // remove handler
                        sessionEvent.onIntString -= SessionEvent_onIntString;
                        // unlink
                        sessionEvent.unPublish();
                        sessionEvent.unSubscribe();
                        Debug.WriteLine("   Last client on session " + sessionEventName);
                    }
                }
            }
        }
Пример #2
0
        public void SendMessageToServer(Message msg)
        {
            try
            {
                var callback = OperationContext.Current.GetCallbackChannel <IMessageToClient>();
                var channel  = OperationContext.Current.Channel;

                TEventEntry channelEvent;
                if (!Lookups.channelToEvent.TryGetValue(channel, out channelEvent))
                {
                    var    queryParameters = HttpUtility.ParseQueryString((OperationContext.Current.IncomingMessageProperties["WebSocketMessageProperty"] as WebSocketMessageProperty).WebSocketContext.RequestUri.Query);
                    var    sessionName     = queryParameters["session"];
                    string clientType      = "";
                    try { clientType = queryParameters["clienttype"]; } catch { }


                    if (sessionName == null || sessionName == "")
                    {
                        sessionName = "unknown";
                    }
                    //var remoteAddress = OperationContext.Current.IncomingMessageHeaders.From;
                    var repmp         = OperationContext.Current.IncomingMessageProperties[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty;
                    var remoteAddress = repmp.Address + ":" + repmp.Port.ToString();

                    // signal start of client on session
                    Debug.WriteLine(DateTime.Now + ": Start of client " + remoteAddress + " on session: " + sessionName + " (" + channel.SessionId.ToString() + ", " + clientType + ")");
                    try
                    {
                        Lookups.channelToClientType[channel]    = clientType;
                        Lookups.channelToRemoteAddress[channel] = remoteAddress;
                        var sessionEvent = Lookups.connection.publish(Lookups.RootEventName + "." + sessionName, false);
                        // make sure we have a root event
                        Lookups.HookupRoot();
                        // check if first channel on session
                        lock (Lookups.rootEvent)
                        {
                            if (!sessionEvent.isSubscribed)
                            {
                                // yes, is the first channel on session
                                Debug.WriteLine("   First client on session " + sessionEvent.eventName);
                                sessionEvent.subscribe();
                                // make client list queryable by session module
                                sessionEvent.onIntString += ClientTrackerChannelInitializer.SessionEvent_onIntString;
                            }
                        }
                        // setup channel
                        channelEvent = Lookups.connection.subscribe(sessionEvent.eventName + "." + channel.SessionId, false);
                        Lookups.channelToEvent[channel] = channelEvent;

                        channelEvent.Tag             = callback;
                        channelEvent.onString       += ChannelEvent_onString;
                        channelEvent.onStreamCreate += ChannelEvent_onStreamCreate;
                        channelEvent.onStreamEnd    += ChannelEvent_onStreamEnd;
                        // make client event manageable by session module
                        channelEvent.onIntString += ChannelEvent_onIntString;
                        // new channel with event name on session event
                        string channelEventNamePostfix;
                        try
                        {
                            channelEventNamePostfix = (clientType != null) && (clientType.Length > 0) ? "&" + clientType : "";
                        }
                        catch
                        {
                            channelEventNamePostfix = "";
                        }

                        sessionEvent.signalIntString(TEventEntry.actionNew, channelEvent.eventName + channelEventNamePostfix);
                        // todo: signal new client on root event?
                    }
                    catch (Exception e)
                    {
                        Debug.WriteLine(DateTime.Now + ": ## exception registering channel: " + e.Message);
                    }
                }
                if (!msg.IsEmpty && ((IChannel)callback).State == CommunicationState.Opened)
                {
                    byte[] returnMessage = msg.GetBody <byte[]>();
                    if (returnMessage.Length > TConnection.imbMaximumPayloadSize / 10) // switch to stream for very large messages
                    {
                        channelEvent.signalStream("string", new MemoryStream(returnMessage));
                    }
                    else
                    {
                        channelEvent.signalString(returnMessage);
                    }
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine(DateTime.Now + ": ## unhandled exception in WebSocketsServer.SendMessageToServer: " + e.Message);
            }
        }