vtortola / websocketlistener Goto Github PK
View Code? Open in Web Editor NEWA lightweight and scalable asynchronous WebSocket listener
Home Page: http://vtortola.github.io/WebSocketListener
A lightweight and scalable asynchronous WebSocket listener
Home Page: http://vtortola.github.io/WebSocketListener
Hi,
Let me know, If both client and server using web socket will be support on windows 7 OS.
Please confirm.
Thanks,
Palmani. K
The function throws an exception if (count < buffer.Length - offset),
but of course this should be if (count > buffer.Length - offset).
If you send an empty string as the payload over the stream, ReadMessage/ReadString and its variants will throw an exception from CheckForDoubleRead line 253
if (CurrentHeader != null)
throw new WebSocketException("There is an ongoing message that is being readed from somewhere else");
I haven't taken the time to research the cause, but I'm guessing the header doesn't get cleared after a 0 payload message.
This can be reproduced by sending an empty string to the EchoServer example.
Hi, is it possible to make a Method to send a Broadcast Message to all connected Clients?
Greetings mok
Hi,
What would you recommend to use as a client side web socket running on mono ?
Do you have plans to add this feature to your library ?
Thanks!
Any plans on adding Owin support?
Most classes in the library are either sealed, non-abstract or have no virtual methods which makes it hard/painful to fully unit test anything that uses those types.
The ideal would be that they implement public interfaces so they can easily be mocked.
For now the only way I found to fully unit test my code is to wrap your API with classes that just implement the interfaces I use, but that makes the whole thing harder to understand than it would otherwise.
Any plan to improve this in a future update ?
Please share some sample code on sending binary data to clients using this library?
sorry it's not an issue but a question: can WebSocketListener be used as a 'bridge' between IIS8 and a Delphi .dll, which works as a module in IIS8. This .dll serves dynamic pages, using these functions: GetExtensionVersion HttpExtensionProc TerminateExtension. Can that dll access websockets, to run both types of traffic on the same port 80?
I'm using '2.1.5.0' from NuGet.
When starting an example, I get this error message:
Error 2 Assembly 'vtortola.WebSockets, Version=2.1.5.0, Culture=neutral, PublicKeyToken=null' uses 'System.Threading.Tasks.Dataflow, Version=4.5.14.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' which has a higher version than referenced assembly 'System.Threading.Tasks.Dataflow, Version=4.5.9.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' d:\Github\WebSocketTest\WebSocketTestSolution\packages\vtortola.WebSocketListener.2.1.5.0\lib\net45\vtortola.WebSockets.dll WebSocketTest
I can only solve this by upgrading TPL to version 4.5.14 and also updating my app.config file.
Hi,
first id like to congrats you for this code;) at least someone is using async as it should :)
But id like to ask you if you have a way to provide simple http server also? I need to provide some files over http/https including js, so then it will connect using websockets. Im using at the moment websocketsharp, its nice, but its not async, and its blocking whole server, when someone got slower connection and send larger messages. I wasnt playing with your code yet much, so im asking without checking it.
If there is http/https now, maybe there is a way to make a plugin?
Regards,
Piotr
We are experiencing an intermittent issue with the WebSocketEventListener
We are running a console application written in VS2013 CSharp running on a windows 2012R2 virtual server with WS unsecure socket listening on port 81 with the following options set.
PingTimeout = TimeSpan.FromSeconds(60),
NegotiationQueueCapacity = Environment.ProcessorCount * 10,
ParallelNegotiations = Environment.ProcessorCount * 2,
NegotiationTimeout = TimeSpan.FromSeconds(6),
WebSocketSendTimeout = TimeSpan.FromSeconds(6),
WebSocketReceiveTimeout = TimeSpan.FromSeconds(6),
SendBufferSize = 8192,
//SubProtocols = _noSubProtocols,
OnHttpNegotiation = null,
UseNagleAlgorithm = true,
PingMode = PingModes.LatencyControl
Everything works perfectly an then periodically we have an issue where a client socket can connect successfully but no events are raised at all within vtortolla and anything we send is not acknowledged. We can disconnect and reconnect as many times as we like so it is not that the EventListener is rejecting or not accepting connections, purely that they are not recognised or raised.
We did turn off IIS and run directly on port 80 for a public test but found that the socket would effectively go in to this state within 2 minutes of not seeing any activity which we figured could be external requests for connection getting the socket or server in to a strange state. Since we reverted to an internal port for testing it takes much longer but we see the same behaviour.
Has anyone seen such behaviour?
I'm developing a server which utilizes your WebSocketListener library. It is being developed under Windows, but will need to be run and tested on linux machines under mono/wine. The server runs fine on Windows, however when I attempt to run the application under wine or mono, I receive this error:
I have all of the dependencies in the folder where the application is being run:
Any enlightenment on what could be causing this issue would be much appreciated.
This is just matter of personal preference I guess, but whats your exact reason to use Int32 instead of int. Also Boolean instead of bool?
See also this related stackoverflow discussion:
http://stackoverflow.com/questions/62503/c-int-or-int32-should-i-care
I am investigation a solution where a native software needs to communicate with a webapp on localhost. I have built the very simple Echo-sample and it works in Chrome and IE 11 but not in Microsoft Edge 25.10586.0.0. I have checked in about:flags that localhost is allowed.
The same javascript is used in all Browser. In Edge, the Onclose event returns 1006 "The connection was closed abnormally, e.g., without sending or receiving a Close control frame" after a couple of seconds.
Do I need to do something to get this working on Edge or is it time to face the reality that it not possible to use websockets on localhosts?
Thanks,
The script used for testing
var ws = new WebSocket("ws://localhost:8005");
ws.onopen = function()
{
// Web Socket is connected, send data using send()
ws.send("Message to send");
alert("Message is sent...");
};
ws.onmessage = function (evt)
{
var received_msg = evt.data;
alert("Message is received...");
};
ws.onclose = function(event)
{
// websocket is closed.
var reason;
alert(event.code);
}
from web socket server, sending binary stream
is it possible to target to specific javascript element (id) ?
or:
how I can combine the binary message, with some 'header' text information ,
so when arriving to client, I can handle the binary, to put it on specific id ,from 'header info'?
how the web socket serving static files (URL) ? means:
in client javascript:
image.src=url1 ;
websocket server:
getting the url1 request, and sending back to client the binary image.
I tested your vtortola websocket with strings,on concurrent users,
it worked perfectly.
any code sample, or link will be appreciated.
When accepting a WebSocket client it seems the HttpRequest URI is not absolute, and hence wrong (almost all Uri type properties throw an exception). It is missing the protocol and hostname/port.
Hi,
Last week a ran into a strange issue when writing a message by way of WebSocketStringExtensions.WriteStringAsync. For some reason, when I called this method from the main thread, Connection.EndWriting was not called. I still don't understand what the problem is here, but the issue appears not to occur when I call WriteStringAsync from a thread other than the main thread, so at least I seem to have a workaround.
While I was investigating the problem, I noticed that I was using WebSocketStringExtensions.WriteString(Async) incorrectly. Judging from the fact that the function is not guarded by semaphore, you appear to have assumed that the function would always be called from the same thread. In my scenario, WriteStringAsync is called by at least two threads, which means that I cannot use the function in its current form.
Given that WriteStringAsync is an async method and that I don't await it, it won't work to acquire the semaphore before the call to WriteStringAsync, because then it would be unclear when to release it. One possible solution is to create an WriteStringThreadSafeAsync function that accepts a semaphore as a function parameter, acquires it, then calls WriteStringAsync, then releases the semaphore in a 'finally' block. The problem with this approach is that you would ideally like the acquisition of the semaphore to adhere to the WebSocketSendTimeout, but this value is inaccessible at this point.
This is why I think best solution may be to let the WebSocketConnection own the semaphore and let it acquire it in Connection.BeginWriting and release it in EndWriting.
I would be interested to hear your thoughts about this.
I'm have an issue when trying to close websocket connection from a chrome browser,
in the client side when I call websocket.close(1000,"Normalclose") server is returning 1006 (Abnormal close) in the 'websocket.onclose' it gives 1006(Abnormal close) as error code.
It can be reproduced using the sample websocket listener console app,
Steps to reproduce
Seems like chrome is sending from "frame" of size 66bytes every 45secs interval, might be "pong" frame.
Is there a way I can make the connection to close normally without any error.
Note: It works fine with Firefox browser, since it does not send any frame after connection is created.
There seems to be a timeout issue at the socket level around 3 minuted 20 seconds.
The underlying socket disconnects while the WebSocket connection remains true.
What's the cure?
Hi,
I've been told that WampSharp has issues with the vtrotola WebSocketListener transport and large messages.
After investigating this, this seems to be an issue that looks like a race condition in WebSocketListener. I'm attaching some code that reproduces this. Note that not every run results with an exception, so it seems this is really some kind of race condition.
See the code here. You need to install vtortola.WebSocketListener, WebSocket4Net and Newtonsoft.Json. The application should crash at some point with this exception:
An unhandled exception of type 'Newtonsoft.Json.JsonReaderException' occurred in Newtonsoft.Json.dll
Additional information: Unterminated string. Expected delimiter: ". Path '[31].tags[0]', line 1, position 32776.
Investigating the received message, we see a substring of the sent JSON ending with this suffix "i��y2���".
You might suspect that this may be a problem related to WebSocket4Net, but it works fine with other WebSocket libraries such as Fleck.
Any help is appreciated,
Thanks!
Elad
I'm trying to find a .NET client/server that does.
I created a simple HTML page for testing purposes. On this HTML page I try to open a webSocket. I run this HTML page locally (on Google Chrome). As a consequence, the handshake header contains the line "Origin: null".
This makes the WebSocket handshake fail because HttpHeadersCollection::Add tries to turn null into an Uri, which it cannot. "Origin: null" does appear to be valid though.
The issue is very easy to fix: I just added a special case to HttpHeadersCollection::Add(), as follows:
case "Origin":
if (string.Compare(value, "null", true) == 0)
uri = null;
else if (!Uri.TryCreate(value, UriKind.Absolute, out uri))
throw new WebSocketException("Cannot parse '" + value + "' as Origin header Uri");
Origin = uri;
break;
Having a null URI does not appear to break the rest of the code, I can keep receiving and sending messages.
BTW, Your library is awesome!
Hi, i'd like to use your nugget but it is not CLS compliant.
Any idea if that's something you can fix ?
Hi,
I've tried running a simple test:
static async void test()
{
Console.WriteLine("Vtortola WebsocketListener Test");
var server = new WebSocketListener(new IPEndPoint(IPAddress.Any, 9999));
var rfc6455 = new WebSocketFactoryRfc6455(server);
server.Standards.RegisterStandard(rfc6455);
server.Start();
while (true)
{
var client = await server.AcceptWebSocketAsync(CancellationToken.None);
}
}
However when attempting to connect a client the following exception is thrown:
vtortola.WebSockets.WebSocketException: Cannot parse 'localhost' as Origin header Uri
at vtortola.WebSockets.HttpHeadersCollection.Add (System.String name, System.String value) [0x00000] in <filename unknown>:0
at vtortola.WebSockets.WebSocketHandshaker.ParseHeader (System.String line, vtortola.WebSockets.WebSocketHandshake handshake) [0x00000] in <filename unknown>:0
at vtortola.WebSockets.WebSocketHandshaker.ReadHttpRequest (System.IO.Stream clientStream, vtortola.WebSockets.WebSocketHandshake handshake) [0x00000] in <filename unknown>:0
at vtortola.WebSockets.WebSocketHandshaker+<HandshakeAsync>d__0.MoveNext () [0x00000] in <filename unknown>:0
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000b] in /private/tmp/source-mono-mac-3.12.0-branch-32/bockbuild-mono-3.12.0-branch/profiles/mono-mac-xamarin/build-root/mono-3.12.0/mcs/class/corlib/System.Runtime.ExceptionServices/ExceptionDispatchInfo.cs:62
at vtortola.WebSockets.WebSocketListener+<AcceptWebSocketAsync>d__12.MoveNext () [0x00000] in <filename unknown>:0
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000b] in /private/tmp/source-mono-mac-3.12.0-branch-32/bockbuild-mono-3.12.0-branch/profiles/mono-mac-xamarin/build-root/mono-3.12.0/mcs/class/corlib/System.Runtime.ExceptionServices/ExceptionDispatchInfo.cs:62
at System.Runtime.CompilerServices.TaskAwaiter`1[vtortola.WebSockets.WebSocket].GetResult () [0x00000] in <filename unknown>:0
at vtortolatests.MainClass+<listen>c__async0.MoveNext ()
A simple example project for binary messages would be super-helpful, for example adding binary support to the echo example. I've found the text readers seem to work great in the async mode, but the binary async reading of messages is trickier. A fully working example would really help, thanks.
In this file you have this piece of code:
private void ClientLeaves()
{
if (!String.IsNullOrWhiteSpace(_session.Room))
{
Broadcast(new { cls = "msg", message = _session.Nick + " leaves the room.", room = _session.Room, nick = "Server", timestamp = DateTime.Now.ToString("hh:mm:ss") });
Broadcast(new { cls = "leave", room = _session.Room, nick = _session.Nick }, _session);
}
}
You have ro replace to this:
Broadcast(new { cls = "msg", message = _session.Nick + " leaves the room.", room = _session.Room, nick = "Server", timestamp = DateTime.Now.ToString("hh:mm:ss") }, _session);
Broadcast(new { cls = "leave", room = _session.Room, nick = _session.Nick }, _session);
Otherwise when you in the chat room and closing tab of the browser then session do not release correctly because it's trying to send message to inexistent connection.
Hi ,
On latest code, I observed that the listener is NOT considering the PingTimeout value setting (for ex: 120 seconds) and it is always sending ping requests every 0.5 seconds. I found that the ping interval was wrongly calculated in LatencyControlPing.cs by using min value between 0.5 and half of PingTimeout value. My understanding is that we should take "max" value instead of "min", please correct me if that is not right?
Thanks,
Trivedi
I'm struggling to get anywhere with with this so far. I'm just running up the echo sample code as a console app and I want a node.js app on the same machine to call functions in it (echo for now).
When I use socket.io-client with something like io.emit('hello') I don't see anything in the console app.
I see AcceptWebSocketClientsAsync being fired intermittently when the console app is running but that's it. The HandleConnecionAsync never fires.
Any pointers what I'm doing wrong?
Thx.
When we connect to multiple clients and send data(json string) to them over websocket using WriteAsync. Will there be any loss of messages? How best we can confirm the delivery of perticular message?
Hello. I'm creating websocket server on localhost. For connecting i'm using proxy Apache/Nginx. Server worked good, but when i open on the browser link http://server/ws/ should be throw exception of bad handshake. The exception not throwing and connection not closing.
I'm trying debug and noticed that in the class HttpNegotiationQueue
in function NegotiateWebSocket
after handshacking, handshake error is null, on line result = new WebSocketNegotiationResult(handshake.Error);
Would be awesome if you could compile the nuget package for the coreclr framework.
Can I do that myself somehow for now?
I have a project where there will only be a single WebSocket at any given time, but a given WebSocket may require transporting a large amount in a given message (as much as a 32 mb).
Right now, my WebSocketListenerOptions
look something like this:
server = new WebSocketListener(endpoint, new WebSocketListenerOptions()
{
PingTimeout = Timeout.InfiniteTimeSpan,
SendBufferSize = 32768,
WebSocketReceiveTimeout = TimeSpan.FromSeconds(15),
WebSocketSendTimeout = TimeSpan.FromSeconds(15),
BufferManager = BufferManager.CreateBufferManager((65536) * 1, 65536)
});
Does anything look incorrect here? Any suggestions would be very helpful.
Just out of curiosity, did you have any plans to implement something similar to websockify in the library?
This code block:
try
{
await _semaphore.WaitAsync(_cancel.Token).ConfigureAwait(false);
var socket = await _sockets.ReceiveAsync(_cancel.Token).ConfigureAwait(false);
NegotiateWebSocket(socket);
}
Shouldn't that be like:
try
{
await _semaphore.WaitAsync(_cancel.Token).ConfigureAwait(false);
var socket = await _sockets.ReceiveAsync(_cancel.Token).ConfigureAwait(false);
await NegotiateWebSocket(socket);
}
Is there a builtin method to determine if a user was disconnected through a ping timeout? Should i keep a list of open sockets and query them periodically to see if they're open?
The TryParse in the WebSocketFrameHeader class uses ToInt16 and ToInt64 rather than treating the payload lengths as unsigned ints (as required by the rfc6455 spec), which causes issues in certain cases (negative payload lengths), which is critical. Lines 98 and 107.
This issue happen when you try to use WebSocketDeflateExtension on Mono 4.2.2
rfc6455.MessageExtensions.RegisterExtension(new WebSocketDeflateExtension());
how to fix it and make it work on Mono?
I did some small tests by using a client based on the chat client from https://www.websocket.org/ and I created a c# test client based on https://github.com/sta/websocket-sharp#websocket-client
When running the WebSocket server based on your chat example, it seems that the server can connect about 50 WebSocket connections per second.
Is this a limitation on your code / my system or do I need to tweak the WebSocketListenerOptions ?
Please advice.
When sending large, binary messages like such
try
{
using (var messageWriter = client.CreateMessageWriter(WebSocketMessageType.Binary))
{
using (var stream = new MemoryStream(data))
{
await stream.CopyToAsync(messageWriter);
}
}
}
catch (Exception)
{
}
There is no indication from the library on the current progress of the message (i.e 10% transfered) or the state of the message until the client receives the entire binary message.
Is there a work around for this or would this need to be an entirely new feature?
Hi,
Thanks for this library. For our use-case we have hundreds of thousands of devices connecting to our service. The amount of messages per device is very low: a few per day. This makes that we are more interested in the maximum amount of concurrent connections that can be reached per typical VM (e.g. AWS m3.large running Linux), than how much messages can be send. Your performance wiki page did not mention this. Have you ever done such a test? And if so, would you be so kind to share the results?
With kind regards,
Joost
In my logs i found this record:
Unhandled Exception:
System.NullReferenceException: Object reference not set to an instance of an object
at vtortola.WebSockets.Rfc6455.WebSocketRfc6455.Dispose (Boolean disposing) <0x41364c50 + 0x00042> in <filename unknown>:0
at vtortola.WebSockets.Rfc6455.WebSocketRfc6455.Finalize () <0x413cac60 + 0x0001d> in <filename unknown>:0
I tried to restore the situation in which it happened, and that's what came out of it.
if the class (WebSocketRfc6455) constructor, an exception is thrown, and then turn on GC.Collect(), function Dispose(bool) call Connection.Dispose(). But property Connection is null, because in the class constructor, an exception is thrown and Connection not set.
Hi,
Where can we get close web socket connection event?
Hi,
I'm experiencing occasional problems when the client has closed the connection (perhaps ungracefully) and then tries to reconnect. The issue is quite difficult to reproduce. I see it about once a week. When it occurs, the symptoms are as follows:
So, it's quite a mystery to me what is going on here. To me this looks like a bug in the TransformBlock class, because I would expect TransformBlock.ReceiveAsync() to return as soon as NegotiateWebSocket has produced a valid WebSocketNegotiationResult. Perhaps you have some ideas?
Hi.
I'm using the server and it works very well.
Only I wanted to know if there is any way to register the listening URL and only answer to the registered URI.
Actually I'm using the OnHttpNegotiation and throwing an exception, but this results in a 503 internal server error (I see it's programmed this way) and I will like to return a 404 with a personalized message.
Is this possible?
Thanks.
Hi,
I try your API for high frequency system (up to 1000 messages/second with 10 clients).
I try PowerWebSocket, a commercial API and your API. What client for a WPF application is the best (I use your EVENT based server)?
thanks
Greetings! This looks like a fantastic API. Is there a chance it can be modified slightly to be PCL-compliant and thus support the ever-growing Xamarin user base? I'd be happy to contribute beer money :)
I saw a closed issue from another user stating that they had to modify the: "default buffer, not buffer manager, and remove some of the .Net logging statements to get it to compile for PCL IOS and Android". Thanks for reading. Cheers from Florida!
Hi, I'm a bit new to WebSockets so please forgive me if this is a stupid question, but how do I connect to a URI?
var server = new WebSocketListener(new IPEndPoint(IPAddress.Any, 8006));
There are no URI overloads for WebSocketListener, and I can't seem to find anything in the options. I'm trying to connect to something like this:
ws://www.example.com:9997/ws
Again, apologies if I missed something obvious.
The example snippet on your main github page uses an object called "messageReader" - where does this come from? I can't understand how to get messageReader from messageReadStream, thanks.
if(messageReadStream.MessageType == WebSocketMessageType.Binary)
{
using (var ms = new MemoryStream())
{
await messageReader.CopyToAsync(ms);
}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.