Skip to content

vtortola/WebSocketListener

Repository files navigation

Build status WebSocketListener


Please read

This project is considered completed. Reported bugs will be fixed, but there is no plans for new features.

@deniszykov has continued its development, adding support for other platforms in his forkdeniszykov/WebSocketListener.


TheWebSocketListenerclass provides simple methods that listen for and accept incoming WebSocket connection requests asynchronously. It is a lightweight listener with an API very similar to theSystem.Net.TcpListenerclass. Itdoes not usethe Microsoft'sSystem.Net.WebSocketsnamespace.

It works with.NET Standard 2.0 since Version 3.0.0.Version 2.2.4is.NET/Mono 4.5 compatible.

WebSocketListenerhas been designed to provide WebSocket connectivity to other applications, in the same way thatSystem.Net.TcpListenerprovides TCP connectivity. It is not a communication framework on its own and it does not provide any kind of publisher/subscriber pattern or reliable messaging beyond TCP.

  • It can work with bothText or Binarymessages.
  • It supportswss://(secure).More info.
  • It supportsper-message deflate compression.More info.
  • It can work withmultiple WebSocket standardssimultaneously.More info
  • It isextensible.More info.
  • It isasynchronous.
  • It supportsMono.More info
  • It has thePing/Pongfunctionalitybuilt-in.
  • It can measureconnection latency.More info
  • It can work withcookies and custom HTTP response statuses.More info
  • It detects and disconnectshalf open connections.
  • It allows tosend and receive messages as streams.WebSocket messages are represented as delimited stream-like objects, that allows integration with other.NET objects like e.g.StreamReaderandStreamWriter.Two different WebSocket messages, yield two different streams.
  • Messages reads and writes are streamed. Big messages are not held in memory during reads or writes.
  • Ithandles partial frames transparently.The WebSocket specification states that a single message can be sent across multiple individual frames. The message stream will allow to read all the message data, no matter if it was sent in a single or multiple frames.
  • Ithandles interleaved control frames transparently.The WebSocket specification states that control frames can appear interleaved with data frames, including between partial frames of the same message. The message stream will allow to read just the message data, it will skip the control frames.

Take a look on theperformance and load testson a simple 'echo' server.

Featured example

This echo server exampleusesNGINXto serve static files and WebSocket connections through the same port, providingSSL terminationfor both. It usesDockerand.Net Core 2.0.

Quickstart

Install

WebSocketListener is available through NuGet

PM> Install-Package vtortola.WebSocketListener

Set up

Setting up a server and start listening for clients is very similar to aTcpListener.An listening endpoint and a WebSocket standard is the minimum needed to set up a server.

varserver=newWebSocketListener(newIPEndPoint(IPAddress.Any,8006));
server.Standards.RegisterStandard(newWebSocketFactoryRfc6455());
server.StartAsync();

The classvtortola.WebSockets.Rfc6455.WebSocketFactoryRfc6455gives support to theRFC 6455,that is the WebSocket standard used at the moment. Future standards can be added in thesame way.

Optionally, you can also:

Accepting clients

Once the server has started, clients can be awaited asynchronously. When a client connects, aWebSocketobject will be returned:

varclient=awaitserver.AcceptWebSocketAsync(cancellationToken);

The client provides means to read and write messages. With the client, as in the underlyingNetworkStream,is possible to write and read at the same time even from different threads, but is not possible to read from two or more threads at the same time, same for writing.

AcceptWebSocketAsyncshould be in a loop to continuously accept new clients, also wrapped in atry/catchsince errors in the negotiation process will be thrown here. Take a look to thesimple host tutorial.

Receiving messages

With the client we canawaita message as a readonly stream:

varmessageReadStream=awaitclient.ReadMessageAsync(cancellationToken);

Messages are a stream-like objects, so is it possible to use regular.NET framework tools to work with them. TheWebSocketMessageReadStream.MessageTypeproperty indicates the kind of content the message contains, so it can be used to select a different handling approach.

The returnedWebSocketMessageReadStreamobject will contain information from the header, like type of message (Text or Binary) but not the message content, neither the message length, since a frame only contains the frame length rather than the total message length, therefore that information could be missleading.

A text message can be read with a simpleStreamReader.It is worth remember that according to the WebSockets specs, it always uses UTF8 for text enconding:

if(messageReadStream.MessageType==WebSocketMessageType.Text)
{
varmsgContent=string.Empty;
using(varsr=newStreamReader(messageReadStream,Encoding.UTF8))
msgContent=awaitsr.ReadToEndAsync();
}

ReadMessageAsyncshould go in a loop, to read messages continuously. Writes and read can be performed at the same time. Take a look to thesimple host tutorial.

Also, a binary message can be read using regular.NET techniques:

if(messageReadStream.MessageType==WebSocketMessageType.Binary)
{
using(varms=newMemoryStream())
{
awaitmessageReadStream.CopyToAsync(ms);
}
}

Sending messages

Writing messages is also easy. TheWebSocketMessageReadStream.CreateMessageWritermethod allows to create a write only message:

using(varmessageWriterStream=client.CreateMessageWriter(WebSocketMessageType.Text))

Once a message writer is created, regular.NET tools can be used to write in it:

using(varsw=newStreamWriter(messageWriterStream,Encoding.UTF8))
{
awaitsw.WriteAsync("Hello World!");
}

Also binary messages:

using(varmessageWriter=ws.CreateMessageWriter(WebSocketMessageType.Binary))
awaitmyFileStream.CopyToAsync(messageWriter);

Example

Take a look on theWebSocketListener samples.

The MIT License (MIT)

Copyright (c) 2014 vtortola

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software" ), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.