예제 #1
0
        public static string GetNamespace(this SocketIOPacket packet)
        {
            switch (packet.Type)
            {
            case SocketIOPacketType.connect:
                if (string.IsNullOrEmpty(packet.Data))
                {
                    return("/");
                }

                return(packet.Data.EndsWith(",")
                        ? packet.Data.Remove(packet.Data.Length - 1)
                        : packet.Data);

            case SocketIOPacketType.eventMessage:
                if (packet.Data.StartsWith("["))
                {
                    return("/");
                }

                var idx = packet.Data.IndexOf("[");
                var nsp = packet.Data.Remove(idx);
                return(nsp.EndsWith(",")
                        ? nsp.Remove(packet.Data.Length - 1)
                        : nsp);

            default: throw new Exception("invalid packet type");
            }
        }
예제 #2
0
        public static SocketIOEvent ExtractEvent(this SocketIOPacket packet)
        {
            if (packet.Type != SocketIOPacketType.eventMessage)
            {
                throw new Exception("invalid packet type");
            }

            var idx      = packet.Data.IndexOf("[");
            var strEvent = packet.Data.Substring(idx);
            var array    = JArray.Parse(strEvent);

            return(new SocketIOEvent(
                       array[0].Value <string>(),
                       array.Count > 1
                    ? array[1]
                    : null
                       ));
        }
예제 #3
0
        public SocketIO(IWebsocket websocket, string url, string path = "/socket.io", string nsp = "/", EngineIO.Options options = null)
        {
            if (!nsp.StartsWith("/"))
            {
                throw new Exception("nsp must begin with '/'");
            }

            this.nsp        = nsp;
            _engineio       = new EngineIO(websocket, url, path, options);
            _engineio.debug = false;
            _engineio
            .on("ping", data =>
            {
                this.emit("ping");
            })
            .on("pong", data =>
            {
                this.emit("pong");
            })
            .on("message", (data) =>
            {
                if (data is string)
                {
                    var packet = new SocketIOPacket(data as string);
                    Logger.Log(string.Format("receive package type = '{0}', data = {1}", packet.Type, data));
                    switch (packet.Type)
                    {
                    case SocketIOPacketType.connect:
                        if (nsp != packet.nsp)
                        {
                            _nspConnectionRequest = true;
                            _engineio.send(nsp.CreateNspConnection().Serialize());
                        }
                        else
                        {
                            _id       = packet.Data.ExtractSid();
                            connected = true;
                            if (_isReconnecting)
                            {
                                _isReconnecting = false;
                                emit("reconnect", _attemptNumber);
                                emit("connect");
                            }
                            else
                            {
                                emit("connect");
                            }
                        }
                        break;

                    case SocketIOPacketType.eventMessage:
                        var e = packet.ExtractEvent();
                        emit(e.Name, e.Data);
                        if (EventReceive != null)
                        {
                            EventReceive(this, new EventArgs <SocketIOEvent>(new SocketIOEvent(e.Name, e.Data)));
                        }
                        break;

                    case SocketIOPacketType.disconnect:
                        disconnect();
                        break;

                    case SocketIOPacketType.error:
                        if (_nspConnectionRequest)
                        {
                            _nspConnectionRequest = false;

                            if (_isReconnecting)
                            {
                                emit("reconnect_error", packet.Data);
                            }
                            else
                            {
                                emit("connect_error", packet.Data);
                            }

                            _engineio.disconnect();
                        }
                        else
                        {
                            emit("error", packet.Data);
                        }
                        break;
                    }
                }
            })
            .on("close", (data) =>
            {
                connected = false;

                if (_disconnectRequest)
                {
                    _disconnectRequest = false;
                    emit("disconnect");
                }
                else
                {
                    if (!_isReconnecting)
                    {
                        emit("connect_error", data);
                    }

                    if (_attemptNumber >= _engineio.options.reconnectionAttempts)
                    {
                        emit("reconnect_failed");
                        emit("disconnect");
                    }
                    else if (_engineio.options.autoConnect)
                    {
                        _isReconnecting = true;
                        if (_attemptNumber > 0)
                        {
                            emit("reconnect_error", data);
                        }
                        _attemptNumber += 1;
                        emit("reconnecting", _attemptNumber);
                        _reconnectTimer.Interval = _engineio.options.reconnectionDelay;
                        _reconnectTimer.Start();
                    }
                }
            })
            .on("error", data =>
            {
                emit("error", data);
            });

            _reconnectTimer           = new Timer();
            _reconnectTimer.AutoReset = false;
            _reconnectTimer.Elapsed  += (s, e) =>
            {
                _engineio.connect();
            };
        }