Example #1
0
        public async Task <Channel <Message> > CreateChannelAsync(
            Symbol publisherId, CancellationToken cancellationToken)
        {
            var clientId = ClientId.Value;

            try {
                var connectionUri = ConnectionUrlResolver.Invoke(this, publisherId);
                _log.LogInformation($"{clientId}: Connecting to {connectionUri}...");
                var ws = ClientWebSocketFactory.Invoke(ServiceProvider);
                using var cts = new CancellationTokenSource(ConnectTimeout);
                using var lts = CancellationTokenSource.CreateLinkedTokenSource(cts.Token, cancellationToken);
                await ws.ConnectAsync(connectionUri, lts.Token).ConfigureAwait(false);

                _log.LogInformation($"{clientId}: Connected.");

                var wsChannel = new WebSocketChannel(ws);
                Channel <string> stringChannel = wsChannel;
                if (MessageLogLevel.HasValue)
                {
                    stringChannel = stringChannel.WithLogger(
                        clientId, _log,
                        MessageLogLevel.GetValueOrDefault(),
                        MessageMaxLength);
                }
                var serializers   = ChannelSerializerPairFactory.Invoke(ServiceProvider);
                var resultChannel = stringChannel.WithSerializers(serializers);
                wsChannel.WhenCompletedAsync(default).ContinueWith(async _ => {
Example #2
0
        public async Task Additional_Middleware_Should_Be_Given_The_Mutated_Context()
        {
            var middleware = new List <MorseL.Sockets.Middleware.IMiddleware>
            {
                new TestMiddleware("First"),
                new TestMiddleware("Second"),
                new TestMiddleware("Third")
            };

            string originalContents = "test stream data";
            string contents         = null;

            var inputStream       = new MemoryStream(Encoding.UTF8.GetBytes(originalContents));
            var mockChannel       = new Mock <IChannel>();
            var connection        = new Connection("connectionId", mockChannel.Object);
            var connectionContext = new MorseL.Sockets.Middleware.ConnectionContext(connection, inputStream);

            var            socket           = new LinkedFakeSocket();
            ILoggerFactory loggerFactory    = new LoggerFactory();
            var            webSocketChannel = new WebSocketChannel(socket, middleware, loggerFactory);

            var delegator = webSocketChannel.BuildMiddlewareDelegate(middleware.GetEnumerator(), async stream => {
                using (var memStream = new MemoryStream())
                {
                    await stream.CopyToAsync(memStream);
                    contents = Encoding.UTF8.GetString(memStream.ToArray());
                }
            });

            await delegator.Invoke(connectionContext);

            string expectedResults = $"SENTThird:SENTSecond:SENTFirst:{originalContents}";

            Assert.Equal(expectedResults, contents);
        }
Example #3
0
        /// <summary>
        /// Processes pending connection requests.
        /// Registers new clients.
        /// </summary>
        private void ProcessListener()
        {
            TcpClient nextClient = null;

            // accept new clients
            lock (listenerSync) {
                if (listener == null)
                {
                    return;
                }
                if (listener.Pending())
                {
                    nextClient = listener.AcceptTcpClient();
                }
            }
            // add new client connection
            // if new client was accepted
            if (nextClient == null)
            {
                return;
            }
            lock (connectionSync) {
                var channel      = new WebSocketChannel(new TcpChannel(nextClient));
                int clientOrigin = GenerateClientOrigin();
                connections.Add(clientOrigin, channel);
                subscriptions.Add(clientOrigin, new List <LiveCaptureSubscription>());
                LogManager.Instance.LogMessage(this, string.Format("New LiveWire client {0}", clientOrigin));
            }
        }
        /// <summary>
        /// 创建网络频道。
        /// </summary>
        /// <param name="name">网络频道名称。</param>
        /// <param name="networkChannelHelper">网络频道辅助器。</param>
        /// <returns>要创建的网络频道。</returns>
        public IWebSocketChannel CreateWebSocketChannel(string name, IWebSocketChannelHelper networkChannelHelper)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new GameFrameworkException("Invalid Channel Name");
            }

            if (networkChannelHelper == null)
            {
                throw new GameFrameworkException("ChannelHelper Can not be null");
            }

            if (HasWebSocketChannel(name))
            {
                throw new GameFrameworkException("Already Exists Channel " + name);
            }

            WebSocketChannel ret = new WebSocketChannel(name, networkChannelHelper);

            ret.NetworkChannelConnected     += OnWebSocketChannelConnected;
            ret.NetworkChannelSended        += OnWebSocketChannelSended;
            ret.NetworkChannelClosed        += OnWebSocketChannelClosed;
            ret.NetworkChannelMissHeartBeat += OnWebSocketChannelMissHeartBeat;
            ret.NetworkChannelError         += OnWebSocketChannelError;

            m_WebSocketChannels.Add(name, ret);
            return(ret);
        }
Example #5
0
        public async Task HandleRequest(HttpContext context)
        {
            if (!context.WebSockets.IsWebSocketRequest)
            {
                context.Response.StatusCode = 400;
                return;
            }
            var publisherId = context.Request.Query[PublisherIdQueryParameterName];

            if (Publisher.Id != publisherId)
            {
                context.Response.StatusCode = 400;
                return;
            }

            var serializers = SerializerFactory.Invoke();
            var clientId    = context.Request.Query[ClientIdQueryParameterName];
            var webSocket   = await context.WebSockets.AcceptWebSocketAsync().ConfigureAwait(false);

            await using var wsChannel = new WebSocketChannel(webSocket);
            var channel = wsChannel
                          .WithSerializer(serializers)
                          .WithId(clientId);

            Publisher.ChannelHub.Attach(channel);
            try {
                await wsChannel.WhenCompleted().ConfigureAwait(false);
            }
            catch (OperationCanceledException) {
                throw;
            }
            catch (Exception e) {
                Log.LogWarning(e, "WebSocket connection was closed with an error");
            }
        }
        /// <summary>
        /// 获取网络频道。
        /// </summary>
        /// <param name="name">网络频道名称。</param>
        /// <returns>要获取的网络频道。</returns>
        public IWebSocketChannel GetWebsocketChannel(string name)
        {
            WebSocketChannel ret = null;

            m_WebSocketChannels.TryGetValue(name, out ret);
            return(ret);
        }
Example #7
0
        public async Task HandleAsync(HttpContext context)
        {
            if (!context.WebSockets.IsWebSocketRequest)
            {
                context.Response.StatusCode = 400;
                return;
            }
            var publisherId = context.Request.Query[PublisherIdQueryParameterName];

            if (Publisher.Id != publisherId)
            {
                context.Response.StatusCode = 400;
                return;
            }

            var serializers = ChannelSerializerPairFactory.Invoke();
            var clientId    = context.Request.Query[ClientIdQueryParameterName];
            var webSocket   = await context.WebSockets.AcceptWebSocketAsync().ConfigureAwait(false);

            await using var wsChannel = new WebSocketChannel(webSocket);
            var channel = wsChannel
                          .WithSerializers(serializers)
                          .WithId(clientId);

            Publisher.ChannelHub.Attach(channel);
            await wsChannel.ReaderTask.ConfigureAwait(false);
        }
            protected override Task OnHandshakeCompleteAsync(WebSocketConnection connection)
            {
                WriteStatus("[server] Wrapping as channel...");
                var channel = new WebSocketChannel(connection, _factory);

                WriteStatus("[server] Initiating channel-based echo...");
                Echo(channel);
                return(base.OnHandshakeCompleteAsync(connection));
            }
        public Task <WebSocket> AcceptAsync(WebSocketAcceptContext context)
        {
            var clientToServer = Channel.CreateUnbounded <WebSocketMessage>();
            var serverToClient = Channel.CreateUnbounded <WebSocketMessage>();

            var clientSocket = new WebSocketChannel(serverToClient.In, clientToServer.Out);
            var serverSocket = new WebSocketChannel(clientToServer.In, serverToClient.Out);

            Client = clientSocket;
            return(Task.FromResult <WebSocket>(serverSocket));
        }
Example #10
0
        public async Task SendAsyncMiddlewareIsCalledOnArbitrarySendAsync(string text)
        {
            var            socket           = new LinkedFakeSocket();
            ILoggerFactory loggerFactory    = new LoggerFactory();
            var            webSocketChannel = new WebSocketChannel(socket, new[] { new Base64Middleware() }, loggerFactory);
            await webSocketChannel.SendAsync(new MemoryStream(Encoding.UTF8.GetBytes(text)));

            var encodedMessage = await socket.ReadToEndAsync();

            var message = Encoding.UTF8.GetString(Convert.FromBase64String(encodedMessage));

            Assert.Equal(message, text);
        }
Example #11
0
        internal WebSocket(IChannelOwner parent, string guid, WebSocketInitializer initializer) : base(parent, guid)
        {
            _channel     = new(guid, parent.Connection, this);
            _initializer = initializer;

            _channel.Close += (_, _) =>
            {
                IsClosed = true;
                Close?.Invoke(this, this);
            };
            _channel.FrameReceived += (_, e) => FrameReceived?.Invoke(this, e);
            _channel.FrameSent     += (_, e) => FrameSent?.Invoke(this, e);
            _channel.SocketError   += (_, e) => SocketError?.Invoke(this, e);
        }
        public Task <WebSocket> AcceptAsync(WebSocketAcceptContext context)
        {
            var clientToServer = Channel.CreateUnbounded <WebSocketMessage>();
            var serverToClient = Channel.CreateUnbounded <WebSocketMessage>();

            var clientSocket = new WebSocketChannel(serverToClient.Reader, clientToServer.Writer);
            var serverSocket = new WebSocketChannel(clientToServer.Reader, serverToClient.Writer);

            Client      = clientSocket;
            SubProtocol = context.SubProtocol;

            _accepted.TrySetResult(null);
            return(Task.FromResult <WebSocket>(serverSocket));
        }
Example #13
0
        static async void RunClientAsync(ChannelFactory channelFactory)
        {
            Console.WriteLine("Creating client...");
            using (var client = await WebSocketConnection.ConnectAsync("ws://127.0.0.1:6080/", channelFactory: channelFactory))
            {
                Console.WriteLine("Wrapping client as channel...");
                var channel = new WebSocketChannel(client, channelFactory);

                string message = "Hello world!";
                Console.WriteLine($"Sending '{message}' via a wrapped channel...");
                string reply = await SendMessageAndWaitForReply(channel, message);

                Console.WriteLine($"Got back: '{reply}'");
            }
        }
Example #14
0
        public async Task SendAsyncMiddlewareIsCalledOnArbitrarySendMessageAsync(string text)
        {
            var            socket           = new LinkedFakeSocket();
            ILoggerFactory loggerFactory    = new LoggerFactory();
            var            webSocketChannel = new WebSocketChannel(socket, new [] { new Base64Middleware() }, loggerFactory);
            await webSocketChannel.SendMessageAsync(new Message
            {
                Data        = text,
                MessageType = MessageType.Text
            });

            var encodedMessage = await socket.ReadToEndAsync();

            var message = MessageSerializer.Deserialize <Message>(Encoding.UTF8.GetString(Convert.FromBase64String(encodedMessage)));

            Assert.Equal(message.Data, text);
        }
        /// <summary>
        /// 销毁网络频道。
        /// </summary>
        /// <param name="name">网络频道名称。</param>
        /// <returns>是否销毁网络频道成功。</returns>
        public bool DestroyWebSocketChannel(string name)
        {
            WebSocketChannel channel = null;

            if (m_WebSocketChannels.TryGetValue(name, out channel))
            {
                channel.NetworkChannelConnected     -= OnWebSocketChannelConnected;
                channel.NetworkChannelSended        -= OnWebSocketChannelSended;
                channel.NetworkChannelClosed        -= OnWebSocketChannelClosed;
                channel.NetworkChannelMissHeartBeat -= OnWebSocketChannelMissHeartBeat;
                channel.NetworkChannelError         -= OnWebSocketChannelError;

                channel.Shutdown();
                m_WebSocketChannels.Remove(name);
            }

            return(false);
        }
Example #16
0
        public async Task SendAsyncMiddlewareCalledInOrderOnArbitrarySendAsync(string text)
        {
            var middlewares = new List <IMiddleware>();

            for (int i = 0; i < 10; i++)
            {
                middlewares.Add(new IncrementalMiddleware());
            }

            var            socket           = new LinkedFakeSocket();
            ILoggerFactory loggerFactory    = new LoggerFactory();
            var            webSocketChannel = new WebSocketChannel(socket, middlewares, loggerFactory);
            await webSocketChannel.SendAsync(new MemoryStream(Encoding.UTF8.GetBytes(text)));

            foreach (var m in middlewares)
            {
                var middleware = (IncrementalMiddleware)m;
                Assert.Equal(middleware.Id, middleware.CalledAt);
            }
        }
        public async Task <Channel <Message> > CreateChannelAsync(
            Symbol publisherId, CancellationToken cancellationToken)
        {
            var clientId = ClientId.Value;

            try {
                var connectionUri = GetConnectionUrl(publisherId);
                _log.LogInformation($"{clientId}: Connecting to {connectionUri}...");
                var ws = ClientWebSocketFactory.Invoke(ServiceProvider);
                using var cts = new CancellationTokenSource(ConnectTimeout);
                using var lts = CancellationTokenSource.CreateLinkedTokenSource(cts.Token, cancellationToken);
                await ws.ConnectAsync(connectionUri, lts.Token).ConfigureAwait(false);

                _log.LogInformation($"{clientId}: Connected.");

                await using var wsChannel = new WebSocketChannel(ws);
                Channel <string> stringChannel = wsChannel;
                if (MessageLogLevel.HasValue)
                {
                    stringChannel = stringChannel.WithLogger(
                        clientId, _log,
                        MessageLogLevel.GetValueOrDefault(),
                        MessageMaxLength);
                }
                var serializers   = ChannelSerializerPairFactory.Invoke(ServiceProvider);
                var resultChannel = stringChannel.WithSerializers(serializers);
                return(resultChannel);
            }
            catch (OperationCanceledException) {
                if (cancellationToken.IsCancellationRequested)
                {
                    throw;
                }
                throw Errors.WebSocketConnectTimeout();
            }
            catch (Exception e) {
                _log.LogError(e, $"{clientId}: Error.");
                throw;
            }
        }
Example #18
0
 /// <summary>
 /// Overrides the service behavior when a WebSocket channel is closed.
 /// </summary>
 /// <param name="channel">The channel being closed.</param>
 /// <param name="statusCode">The status code sent by the remote side in its request to close the connection. </param>
 /// <param name="reason">The text description of status code.</param>
 /// <remarks>
 /// Overriding this method is not necessary unless you need to perform an action when the channel is closed.
 /// </remarks>
 public override void OnClose(WebSocketChannel channel, short statusCode, string reason)
 {
     base.OnClose(channel, statusCode, reason);
 }
Example #19
0
 /// <summary>
 /// Overrides the service behavior when a WebSocket channel is established.
 /// </summary>
 /// <param name="channel">The channel that was established.</param>
 /// <remarks>
 /// Overriding this method is not necessary unless you need to perform an action when the channel is established.
 /// </remarks>
 public override void OnOpen(WebSocketChannel channel)
 {
     base.OnOpen(channel);
     // Sends a ping to the remote endpoint.
     channel.SendPing();
 }
Example #20
0
 public override void OnMessage(WebSocketChannel channel, string text)
 {
     Console.WriteLine("Received text message: '{0}'", text);
 
 }
Example #21
0
 /// <summary>
 /// Handles inbound binary messages.
 /// </summary>
 /// <param name="channel">The channel through which the inbound message was received.</param>
 /// <param name="buffer">The segment of the byte array containing the binary message payload.</param>
 public override void OnMessage(WebSocketChannel channel, ArraySegment<byte> binary)
 {
     Console.WriteLine("Received binary message: " + Convert.ToBase64String(binary.Array, binary.Offset, binary.Count));
 }
        private void OnWebSocketChannelClosed(WebSocketChannel networkChannel)
        {
            var args = ReferencePool.Acquire <WebSocketClosedEventArgs> ().Fill(networkChannel);

            GameEntry.Event.Fire(this, args);
        }
 /// <summary>
 /// 获取所有网络频道。
 /// </summary>
 /// <returns>所有网络频道。</returns>
 public IWebSocketChannel[] GetAllWebSocketChannels()
 {
     WebSocketChannel[] ret = new WebSocketChannel[m_WebSocketChannels.Count];
     m_WebSocketChannels.Values.CopyTo(ret, 0);
     return(ret);
 }
Example #24
0
 public static IChannel Create(Uri endpointUri, WebSocketConfig config, CancellationToken token)
 {
     return(WebSocketChannel.Create(endpointUri, config, token));
 }
Example #25
0
 public static IChannel Create(WebSocketConfig config, HttpContext context,
                               System.Net.WebSockets.WebSocket socket, CancellationToken token)
 {
     return(WebSocketChannel.Create(context, socket, config, token));
 }
Example #26
0
 public static IChannel Create(HttpContext context, WebSocketConfig config, CancellationToken token)
 {
     return(WebSocketChannel.Create(context, config, token));
 }
        private void OnWebSocketChannelSended(WebSocketChannel networkChannel, int bytesSent, object userData)
        {
            var args = ReferencePool.Acquire <WebSocketSentEventArgs> ().Fill(networkChannel, bytesSent, userData);

            GameEntry.Event.Fire(this, args);
        }
        private void OnWebSocketChannelMissHeartBeat(WebSocketChannel networkChannel, int missHeartBeatCount)
        {
            var args = ReferencePool.Acquire <WebSocketMissHeartBeatEventArgs> ().Fill(networkChannel, missHeartBeatCount);

            GameEntry.Event.Fire(this, args);
        }
        private void OnWebSocketChannelError(WebSocketChannel networkChannel, GameFramework.Network.NetworkErrorCode errorCode, string errorMessage)
        {
            var args = ReferencePool.Acquire <WebSocketErrorEventArgs> ().Fill(networkChannel, errorCode, errorMessage);

            GameEntry.Event.Fire(this, args);
        }
        private void OnWebSocketChannelConnected(WebSocketChannel networkChannel, object userData)
        {
            var args = ReferencePool.Acquire <WebSocketConnectedEventArgs> ().Fill(networkChannel, userData);

            GameEntry.Event.Fire(this, args);
        }
Example #31
0
 /// <summary>
 /// Overrides the service behavior when a WebSocket channel encounters an exception.
 /// </summary>
 /// <param name="channel">The channel that encountered the exception.</param>
 /// <param name="e">The exception encountered by the channel.</param>
 public override void OnError(WebSocketChannel channel, Exception e)
 {
     base.OnError(channel, e);
 }
Example #32
0
 /// <summary>
 ///     Configuration function for DotNetToJScript and Unit Tests
 ///     To use with JScript:
 ///     o.Configure('ws://127.0.0.1/bws');
 ///     o.Go()
 /// </summary>
 /// <param name="url"></param>
 public void Configure(string url)
 {
     BeaconChannel = new BeaconChannel();
     ServerChannel = new WebSocketChannel(url);
     UrlEndpoint   = url;
 }
Example #33
0
 public static IChannel Create(Uri endpointUri, string securityToken, string subProtocol, WebSocketConfig config,
                               CancellationToken token)
 {
     return(WebSocketChannel.Create(endpointUri, securityToken, subProtocol, config, token));
 }
Example #34
0
        /// <summary>
        /// Processes active connections.
        /// Handles received messages and detects closed clients.
        /// </summary>
        private void ProcessConnections()
        {
            lock (connectionSync) {
                LinkedList <int> toRemove = null;
                foreach (var pair in connections)
                {
                    WebSocketChannel channel = pair.Value;
                    int clientOrigin         = pair.Key;
                    channel.Process();
                    // handle incoming requests and updates
                    // request handling may involve processing delays
                    // so each request is wrapped in a new task to avoid user-observable lockups
                    // a downside of this implementation is that consecutive requests could be handeled out of order
                    while (channel.AvailableMessageNo > 0)
                    {
                        var message             = channel.EmitMessage();
                        Task <JsonString> task2 = new Task <JsonString>(delegate {
                            JsonString request;
                            try {
                                request = JsonString.Parse(message.Text);
                            } catch (FormatException) {
                                LogManager.Instance.LogError(this, string.Format("failed to parse JSON from client {0}: {1}",
                                                                                 clientOrigin, message.Text));
                                return(null);
                            }
                            return(new LiveRequestHandler(this, clientOrigin).Respond(request));
                        });

                        task2.ContinueWith((Task finished, object result) => {
                            Exception e = finished.Exception;
                            if (e == null)
                            {
                                LogManager.Instance.LogError(this, string.Format("Task failed but no exception was thrown while processing request\n{0}",
                                                                                 message.Text));
                                return;
                            }
                            LogManager.Instance.LogMessage(this, string.Format("{0}\noccurred while processing request\n{1}",
                                                                               e, message.Text));
                        }, TaskContinuationOptions.OnlyOnFaulted);

                        task2.ContinueWith((Task finished, object result) => {
                            LogManager.Instance.LogWarning(this, string.Format("Cancelled task unexpectedly while processing request\n{1}",
                                                                               message.Text));
                        }, TaskContinuationOptions.OnlyOnCanceled);

                        pendingRequests.AddLast(task2);
                        task2.Start();
                    }
                    // close and remove disconnected clients
                    if (channel.State == WebChannelState.InitFailed || channel.State == WebChannelState.Closed)
                    {
                        if (channel.State == WebChannelState.InitFailed)
                        {
                            LogManager.Instance.LogError(this, string.Format("LiveWire client {0} failed to connect",
                                                                             clientOrigin));
                        }
                        if (channel.State == WebChannelState.Closed)
                        {
                            LogManager.Instance.LogMessage(this, string.Format("LiveWire client {0} disconnected",
                                                                               clientOrigin));
                        }
                        channel.Close(true);
                        if (toRemove == null)
                        {
                            toRemove = new LinkedList <int>();
                        }
                        toRemove.AddLast(clientOrigin);
                    }
                    // TODO implement pinging in order to detect suspended connections
                }
                // finally remove dead connections and kill corresponding subscriptions
                if (toRemove != null)
                {
                    foreach (int origin in toRemove)
                    {
                        connections[origin].Close(true);
                        connections.Remove(origin);
                        foreach (var sub in subscriptions[origin])
                        {
                            if (!sub.IsCancelled)
                            {
                                sub.Cancel();
                            }
                            sub.Dispose();
                        }
                        subscriptions.Remove(origin);
                    }
                }
            }
        }
Example #35
0
 public static IChannel Create(Uri endpointUri, X509Certificate2 certificate, string subProtocol,
                               WebSocketConfig config, CancellationToken token)
 {
     return(WebSocketChannel.Create(endpointUri, certificate, subProtocol, config, token));
 }