예제 #1
0
        public async Task Connect(CancellationToken cancellationToken = default)
        {
            TransitionState(ConnectionState.Connecting);
            try {
                await ConnectImpl(cancellationToken);

                StartHandshaking();

                if (Handshaker != null)
                {
                    Log.Info($"{this}: Handshaking...");

                    HandshakeResult = await Handshaker.Handshake(this, cancellationToken);

                    if (!HandshakeResult.Successful)
                    {
                        var ex = new HandshakeException(HandshakeResult.ErrorCode);
                        Log.Info($"{this}: Handshake Failed {HandshakeResult.ErrorCode}: {ex.Message}");
                        throw ex;
                    }

                    User = HandshakeResult.User;
                }

                TransitionState(ConnectionState.Connected);
            } catch (Exception) {
                TransitionState(ConnectionState.Closed);
                throw;
            }
        }
예제 #2
0
 public Handler(Handshaker handshaker)
 {
     this.handshaker = handshaker;
 }
예제 #3
0
        void TestHttpResponseAndFrameInSameBuffer(bool codec)
        {
            string url = "ws://localhost:9999/ws";
            WebSocketClientHandshaker shaker = this.NewHandshaker(new Uri(url));
            var handshaker = new Handshaker(shaker);

            // use randomBytes helper from utils to check that it functions properly
            byte[] data = WebSocketUtil.RandomBytes(24);

            // Create a EmbeddedChannel which we will use to encode a BinaryWebsocketFrame to bytes and so use these
            // to test the actual handshaker.
            var factory = new WebSocketServerHandshakerFactory(url, null, false);
            IFullHttpRequest          request = shaker.NewHandshakeRequest();
            WebSocketServerHandshaker socketServerHandshaker = factory.NewHandshaker(request);

            request.Release();
            var websocketChannel = new EmbeddedChannel(socketServerHandshaker.NewWebSocketEncoder(),
                                                       socketServerHandshaker.NewWebsocketDecoder());

            Assert.True(websocketChannel.WriteOutbound(new BinaryWebSocketFrame(Unpooled.WrappedBuffer(data))));

            byte[] bytes = Encoding.ASCII.GetBytes("HTTP/1.1 101 Switching Protocols\r\nContent-Length: 0\r\n\r\n");

            CompositeByteBuffer compositeByteBuf = Unpooled.CompositeBuffer();

            compositeByteBuf.AddComponent(true, Unpooled.WrappedBuffer(bytes));
            for (; ;)
            {
                var frameBytes = websocketChannel.ReadOutbound <IByteBuffer>();
                if (frameBytes == null)
                {
                    break;
                }
                compositeByteBuf.AddComponent(true, frameBytes);
            }

            var ch = new EmbeddedChannel(new HttpObjectAggregator(int.MaxValue), new Handler(handshaker));

            if (codec)
            {
                ch.Pipeline.AddFirst(new HttpClientCodec());
            }
            else
            {
                ch.Pipeline.AddFirst(new HttpRequestEncoder(), new HttpResponseDecoder());
            }

            // We need to first write the request as HttpClientCodec will fail if we receive a response before a request
            // was written.
            shaker.HandshakeAsync(ch).Wait();
            for (; ;)
            {
                // Just consume the bytes, we are not interested in these.
                var buf = ch.ReadOutbound <IByteBuffer>();
                if (buf == null)
                {
                    break;
                }
                buf.Release();
            }
            Assert.True(ch.WriteInbound(compositeByteBuf));
            Assert.True(ch.Finish());

            var         frame  = ch.ReadInbound <BinaryWebSocketFrame>();
            IByteBuffer expect = Unpooled.WrappedBuffer(data);

            try
            {
                Assert.Equal(expect, frame.Content);
                Assert.True(frame.IsFinalFragment);
                Assert.Equal(0, frame.Rsv);
            }
            finally
            {
                expect.Release();
                frame.Release();
            }
        }
예제 #4
0
파일: GMApplication.cs 프로젝트: abel/sinan
        /// <summary>
        /// 初始化网络监听
        /// </summary>
        /// <param name="path"></param>
        private void InitNetFacade(string path)
        {
            string policy = null;
            try
            {
                using (FileStream fs = File.OpenRead(Path.Combine(path, "crossdomain.txt")))
                using (StreamReader sr = new StreamReader(fs, Encoding.UTF8, false))
                {
                    policy = sr.ReadToEnd();
                }
            }
            catch { }

            GMManager.Instance.Load(Path.Combine(path, "GMList.txt"));
            FrontManager.Instance.Load(Path.Combine(path, "FrontIP.txt"));

            AmfStringZip zip = new CommandMap();
            zip.Load(Path.Combine(path, "Command.txt"));

            string ip = "0.0.0.0";
            string ports = "8005";
            int maxClient = 1000;
            int maxWaitSend = 64;

            const int receiveSize = 8 * 1024;
            const int sendSize = 64 * 1024;

            AmfCodec.Init(maxClient, zip);
            IHandshake hander = new Handshaker(policy);

            CommandProcessor gameProcessor = new CommandProcessor(receiveSize, zip);
            SessionFactory gameFactory = new SessionFactory(receiveSize, sendSize, maxWaitSend, gameProcessor);
            server = new GMService(gameFactory, gameFactory, hander);
            server.Start(ip, ports.Split(new char[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries));
        }
예제 #5
0
        protected async Task ProcessReceivedData(ulong packetId, byte[] data, ISerializer serializer)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }
            if (serializer == null)
            {
                throw new ArgumentNullException(nameof(serializer));
            }

            if (State == ConnectionState.Closed)
            {
                throw new DisconnectedException();
            }

            var serializedPacket = SerializedPacket.Read(data);

            Log.TracePacketReceived(this, serializedPacket);

            {
                var args = new PacketReceivedEventArgs()
                {
                    PacketId   = packetId,
                    Packet     = serializedPacket,
                    Connection = this
                };

                var packetEventHandler = PacketReceived;

                if (packetEventHandler != null)
                {
                    foreach (var handler in packetEventHandler.GetInvocationList().Cast <PacketReceived>())
                    {
                        if (State == ConnectionState.Closed)
                        {
                            throw new DisconnectedException();
                        }

                        try {
                            await handler(this, args);
                        } catch (Exception ex) {
                            Log.Error($"Error in {nameof(PacketReceived)} event handler", ex);
                        }

                        if (args.IsHandled)
                        {
                            return;
                        }
                    }
                }
            }

            if (State == ConnectionState.Closed)
            {
                throw new DisconnectedException();
            }

            Packet packet;

            try {
                packet = serializedPacket.DeserializePacket(serializer);
            } catch (Exception ex) {
                throw new InvalidDataException($"Error deserializing {serializedPacket}: {ex.Message}", data, ex);
            }

            if (State == ConnectionState.Closed)
            {
                throw new DisconnectedException();
            }

            if (packet is HandshakeRequestPacket helloPacket)
            {
                //TODO: Move this into the Server class

                if (Handshaker == null)
                {
                    throw new InvalidOperationException($"{this}: Can't handle {helloPacket} because there is no {nameof(Handshaker)}");
                }

                HandshakeResult result;
                try {
                    result = await Handshaker.OnHandshakeRequest(helloPacket, this, ClosedCancellationToken);
                } catch (Exception ex) {
                    result = HandshakeResult.Failure("Handshake Failed");

                    Log.Error($"{this}: Handshake Failure: {ex}");
                }

                if (result.Successful)
                {
                    User = result.User;
                }

                var response = new ResponsePacket(result);

                await Respond(packetId, response, ClosedCancellationToken);

                TransitionState(result.Successful ? ConnectionState.Connected : ConnectionState.Closed);
            }
            else if (packet is RequestPacket requestPacket)
            {
                var requestContext = new RequestContext()
                {
                    Client     = Client,
                    Server     = Server,
                    Connection = this
                };

                var requestEventHandler = RequestReceived;

                if (requestEventHandler == null)
                {
                    throw new InvalidOperationException($"{this}: Receiving Requests, but nothing is reading them.");
                }

                requestPacket.Context = requestContext;

                var args = new RequestReceivedEventArgs()
                {
                    Request = requestPacket,
                    Context = requestContext
                };

                foreach (var handler in requestEventHandler.GetInvocationList().Cast <RequestReceived>())
                {
                    object result = null;
                    try {
                        result = await handler(this, args);
                    } catch (Exception ex) {
                        Log.Error($"{this}: Error invoking event {nameof(RequestReceived)}: {ex}");
                    }

                    if (result != null)
                    {
                        args.Response  = result;
                        args.IsHandled = true;
                    }

                    if (args.IsHandled)
                    {
                        break;
                    }
                }

                if (requestPacket.Flags.HasFlag(PacketFlag.AckRequired))
                {
                    var unhandledRequestResponse = new ResponsePacket(new ErrorResponseData(ErrorResponseCodes.UnhandledRequest, $"Packet {requestPacket} not expected.", false));

                    var response = (!args.IsHandled ? unhandledRequestResponse : new ResponsePacket(args.Response));

                    try {
                        await Respond(packetId, response, ClosedCancellationToken);
                    } catch (Exception ex) {
                        Log.Error($"{this}: Error sending response to Request {requestPacket}: Response={response}: {ex}");
                    }
                }
            }
            else if (packet is IAck ack)
            {
                if (_awaitingAck.TryGetValue(ack.PacketId, out var tcs))
                {
                    tcs.SetResult(packet);
                }
                else
                {
                    Log.Warn($"{this}: Ack: Could not find packet #{ack.PacketId}");
                }
            }
            else
            {
                throw new InvalidDataException($"{this}: {packet.GetType().Name} packet not supported.");
            }
        }
예제 #6
0
        /// <summary>
        /// 初始化网络监听
        /// </summary>
        /// <param name="crossdomain"></param>
        private void InitNetFacade(string crossdomain)
        {
            string policy = null;
            try
            {
                if (!string.IsNullOrEmpty(crossdomain))
                {
                    using (FileStream fs = File.OpenRead(crossdomain))
                    using (StreamReader sr = new StreamReader(fs, Encoding.UTF8, false))
                    {
                        policy = sr.ReadToEnd();
                    }
                }
            }
            catch { }

            int maxClient = ConfigLoader.Config.MaxClient;
            int sendQueueSize = ConfigLoader.Config.SendQueueSize;

            const int receiveSize = 8 * 1024;
            const int sendSize = 64 * 1024;

            AmfCodec.Init(maxClient, CommandManager.Instance);
            IHandshake hander = new Handshaker(policy);

            GMProcessor gmProcessor = new GMProcessor(receiveSize);
            SessionFactory gmFactory = new SessionFactory(8, receiveSize, sendSize, 8, gmProcessor);
            gmServer = new AmfServer(gmFactory, gmFactory, hander);
            gmServer.Start(ConfigLoader.Config.EpGM);

            GameProcessor gameProcessor = new GameProcessor(receiveSize);
            SessionFactory gameFactory = new SessionFactory(maxClient, receiveSize, sendSize, sendQueueSize, gameProcessor);
            server = new AmfServer(gameFactory, gameFactory, hander);
            server.Start(ConfigLoader.Config.EpGame);

            Notifier.Instance.Publish(new Notification(GMCommand.GMStart, new object[] { this }), false);
        }