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 _ => {
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); }
/// <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); }
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); }
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)); }
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); }
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)); }
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}'"); } }
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); }
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; } }
/// <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); }
/// <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(); }
public override void OnMessage(WebSocketChannel channel, string text) { Console.WriteLine("Received text message: '{0}'", text); }
/// <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); }
public static IChannel Create(Uri endpointUri, WebSocketConfig config, CancellationToken token) { return(WebSocketChannel.Create(endpointUri, config, token)); }
public static IChannel Create(WebSocketConfig config, HttpContext context, System.Net.WebSockets.WebSocket socket, CancellationToken token) { return(WebSocketChannel.Create(context, socket, config, token)); }
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); }
/// <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); }
/// <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; }
public static IChannel Create(Uri endpointUri, string securityToken, string subProtocol, WebSocketConfig config, CancellationToken token) { return(WebSocketChannel.Create(endpointUri, securityToken, subProtocol, config, token)); }
/// <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); } } } }
public static IChannel Create(Uri endpointUri, X509Certificate2 certificate, string subProtocol, WebSocketConfig config, CancellationToken token) { return(WebSocketChannel.Create(endpointUri, certificate, subProtocol, config, token)); }