Code Monkey home page Code Monkey logo

fleck's Introduction

Fleck

Build status NuGet

Fleck is a WebSocket server implementation in C#. Branched from the Nugget project, Fleck requires no inheritance, container, or additional references.

Fleck has no dependency on HttpListener or HTTP.sys meaning that it will work on Windows 7 and Server 2008 hosts. WebSocket Remarks - Microsoft Docs

Example

The following is an example that will echo to a client.

var server = new WebSocketServer("ws://0.0.0.0:8181");
server.Start(socket =>
{
  socket.OnOpen = () => Console.WriteLine("Open!");
  socket.OnClose = () => Console.WriteLine("Close!");
  socket.OnMessage = message => socket.Send(message);
});
        

Supported WebSocket Versions

Fleck supports several WebSocket versions of modern web browsers

  • Hixie-Draft-76/Hybi-00 (Safari 5, Chrome < 14, Firefox 4 (when enabled))
  • Hybi-07 (Firefox 6)
  • Hybi-10 (Chrome 14-16, Firefox 7)
  • Hybi-13 (Chrome 17+, Firefox 11+, Safari 6+, Edge 13+(?))

Secure WebSockets (wss://)

Enabling secure connections requires two things: using the scheme wss instead of ws, and pointing Fleck to an x509 certificate containing a public and private key

var server = new WebSocketServer("wss://0.0.0.0:8431");
server.Certificate = new X509Certificate2("MyCert.pfx");
server.Start(socket =>
{
  //...use as normal
});

Having issues making a certificate? See this guide to creating an x509 by @AdrianBathurst

SubProtocol Negotiation

To enable negotiation of subprotocols, specify the supported protocols on the WebSocketServer.SupportedSubProtocols property. The negotiated subprotocol will be available on the socket's ConnectionInfo.NegotiatedSubProtocol.

If no supported subprotocols are found on the client request (the Sec-WebSocket-Protocol header), the connection will be closed.

var server = new WebSocketServer("ws://0.0.0.0:8181");
server.SupportedSubProtocols = new []{ "superchat", "chat" };
server.Start(socket =>
{
  //socket.ConnectionInfo.NegotiatedSubProtocol is populated
});

Custom Logging

Fleck can log into Log4Net or any other third party logging system. Just override the FleckLog.LogAction property with the desired behavior.

ILog logger = LogManager.GetLogger(typeof(FleckLog));

FleckLog.LogAction = (level, message, ex) => {
  switch(level) {
    case LogLevel.Debug:
      logger.Debug(message, ex);
      break;
    case LogLevel.Error:
      logger.Error(message, ex);
      break;
    case LogLevel.Warn:
      logger.Warn(message, ex);
      break;
    default:
      logger.Info(message, ex);
      break;
  }
};

Disable Nagle's Algorithm

Set NoDelay to true on the WebSocketConnection.ListenerSocket

var server = new WebSocketServer("ws://0.0.0.0:8181");
server.ListenerSocket.NoDelay = true;
server.Start(socket =>
{
  //Child connections will not use Nagle's Algorithm
});

Auto Restart After Listen Error

Set RestartAfterListenError to true on the WebSocketConnection

var server = new WebSocketServer("ws://0.0.0.0:8181");
server.RestartAfterListenError = true;
server.Start(socket =>
{
  //...use as normal
});

fleck's People

Contributors

artfulhacker avatar danielwertheim avatar darkl avatar davidfowl avatar davidlundy avatar galbarm avatar jacobstanley avatar jazain avatar jespertheend avatar jmarnold avatar joeyespo avatar kduongluu avatar klugerama avatar lemonmojo avatar notgiven688 avatar paintninja avatar raspi avatar rgl avatar rickparrish avatar rlweb avatar silvenga avatar statianzo avatar trew avatar ugs avatar xpaw avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fleck's Issues

Parsing handshake before all data has been received results in an ArgumentOutOfRangeException.

Hi,

occasionally, can be reproduced by doing a ton of fast refreshes, I'm getting an ArgumentOutOfRangeException in the ParseClientHandshake function.

What happens is that the challenge if being read from an empty buffer, so this line:

var challenge = new ArraySegment(byteShake.Array, byteShake.Count - 8, 8); // -8 : eight byte challenge

where 8 is subtracted from 0 results in a negative number and the exception is thrown.

This could be fixed by checking if there is a minimal number of bytes in the buffer but perhaps the TaskFactory / socket IO has a more elegant / robust way of ensuring a certain amount of data has been written.

cheers,
Ernst

exception details::

System.ArgumentOutOfRangeException occurred
Message=Non-negative number required.
Parameter name: offset
Source=mscorlib
ParamName=offset
StackTrace:
at System.ArraySegment1..ctor(T[] array, Int32 offset, Int32 count) at Fleck.HandshakeHandler.ParseClientHandshake(ArraySegment1 byteShake)
InnerException:

Binding to port 80 or 443

Hi,

is this easily possible?
Running on custom ports (rather than default http ports) defeats some of the purpose od WebSockets (opening ports on firewalls).
Thanks.

[Feature] Add unique id for a connection

Hi,

Is it possible to add a unique id for IWebSocketConnection? this is for better connection managemet in the server.
Looking at the Sample application, there is a List of IWebSocketConnection and the Add/Remove is done using the WebSocketConnection object itself, I suppose it is using the GetHashCode method to test equality, this could be an issuse since "The default implementation of the GetHashCode method does not guarantee unique return values for different objects" (http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx), so theoretically one could remove the wrong connection object...

I thought of something like:

public interface IWebSocketConnection
{
    int ID { get; }
    ...
    ...
}

and in WebSocketServer.cs

public class WebSocketServer : IWebSocketServer
{
    private int _id = 1;
    ...
    ...
    ...

    private void OnClientConnect(ISocket clientSocket)
    {
        ...
        ...

       connection = new WebSocketConnection(...);
       // This is just an example, can use any other method to generate unique id. 
       connection.ID = Interlocked.Increment(ref _id);
        ...
        ...
   }
}

Thx.

Interface to logging

Great project.
Would be nice if the logging could be used via an interface, and not just via the console, so that one can use his favourite logging with this project.

Exception on WebSocketServer Dispose()

As seen here:
https://gist.github.com/1672857

using (var server = new WebSocketServer("ws://localhost:8181"))
{
    server.Start(connection => { });
}

24/01/2012 21:29:32 [Info] Server started at ws://localhost:8181
24/01/2012 21:29:32 [Error] Listener socket is closed System.AggregateException:
 One or more errors occurred. ---> System.ObjectDisposedException: Cannot access
 a disposed object.
Object name: 'System.Net.Sockets.Socket'.
   at System.Net.Sockets.Socket.EndAccept(IAsyncResult asyncResult)
   at Fleck.SocketWrapper.<Accept>b__c(IAsyncResult r)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar,
Func`2 endFunction, Action`1 endAction, Task`1 promise)
   --- End of inner exception stack trace ---
---> (Inner Exception #0) System.ObjectDisposedException: Cannot access a dispos
ed object.
Object name: 'System.Net.Sockets.Socket'.
   at System.Net.Sockets.Socket.EndAccept(IAsyncResult asyncResult)
   at Fleck.SocketWrapper.<Accept>b__c(IAsyncResult r)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar,
Func`2 endFunction, Action`1 endAction, Task`1 promise)<---

Bring Back 3.5 Support

I believe the only thing holding back 3.5 is SocketWrapper's use of the TPL. Another implementation of ISocket could fix this.

Integrate with existing HTTP server

I would like if I could use Fleck to support WebSockets while still using only one port for both the normal HTTP and the WebSockets traffic. Is there any way I could transfer the HTTP UPGRADE request to Fleck from my regular HTTP server? The request (HTTP headers, etc.) would already be parsed and I could pass the socket connection to Fleck if Fleck supported it.

The main reason for this is so that the user won't have to use two ports for my web app.

Example Server.cs a little overwhelming and confusing.

Although I applaud the use of the Action delegate (http://msdn.microsoft.com/en-us/library/018hxwa8.aspx), I must admit that it is it a bit confusing to debug and may be overwhelming to people who are new to C#. This is why I have rewritten the example, expanding the Action Delegate which some people may find easier to understand:

    static WebSocketServer mServer;
    static List<IWebSocketConnection> mClients;

    private static void OnWebSocketConnection(IWebSocketConnection socket)
    {
        socket.OnError = delegate(Exception ex) { OnError(socket, ex); };
        socket.OnOpen = delegate() { OnOpen(socket); };
        socket.OnClose = delegate() { OnClose(socket); };
        socket.OnMessage = delegate(string message) { OnMessage(socket, message); };
    }

    private static void OnError(IWebSocketConnection socket, Exception ex)
    {
        Console.WriteLine("Error: " + ex.Message);
    }

    private static void OnOpen(IWebSocketConnection socket)
    {
        IWebSocketConnectionInfo conn = socket.ConnectionInfo;
        Console.WriteLine("Open! (" + conn.ClientIpAddress + ":" + conn.ClientPort.ToString() + ")");
        mClients.Add(socket);
    }

    private static void OnClose(IWebSocketConnection socket)
    {
        Console.WriteLine("Close!");
        mClients.Remove(socket);
    }

    private static void OnMessage(IWebSocketConnection socket, string message)
    {
        Console.WriteLine(message);

        Action<IWebSocketConnection> action = delegate(IWebSocketConnection s) { BroadcastEcho(s, message); };
        mClients.ToList().ForEach(action);
    }

    private static void BroadcastEcho(IWebSocketConnection s, string message)
    {
        s.Send("Echo: " + message);
    }

    static void Main()
    {
        FleckLog.Level = LogLevel.Debug;
        mClients = new List<IWebSocketConnection>();
        string WSLocation;
        WSLocation = "ws://localhost:8181";

        mServer = new WebSocketServer(WSLocation);
        Action<IWebSocketConnection> config = delegate(IWebSocketConnection socket) { OnWebSocketConnection(socket); };
        mServer.Start(config);

        var input = Console.ReadLine();
        while (input != "exit")
        {
            foreach (IWebSocketConnection socket in mClients.ToList())
            {
                socket.Send(input);
            }
            input = Console.ReadLine();
        }
    }

Phonegap websocket plugin

Hi
i using websocket plugin in phonegap apps.
websocket plugin -> https://github.com/hakanertug/websocket-android-phonegap

I'm sending data from phonegap to fleck server but server fired this codes

when we debug the version is handled 75

    public static IHandler BuildHandler(WebSocketHttpRequest request, Action<string> onMessage, Action onClose, Action<byte[]> onBinary)
    {
        var version = GetVersion(request);

        switch (version)
        {
            case "76":
                return Draft76Handler.Create(request, onMessage);
            case "7":
            case "8":
            case "13":
                return Hybi13Handler.Create(request, onMessage, onClose, onBinary);
        }

        throw new WebSocketException(WebSocketStatusCodes.UnsupportedDataType);
    } -> error line :  Exception of type 'Fleck.WebSocketException' was thrown.

Thanks...

Header case sensitivity

I'm running Fleck under OS X using Mono 3. It refused to service any request and recognize subprotocol. Then I realized that the WebSocketHttpRequest's Headers dictionary had all lower-case values (on the wire they had the expected case). I suspect that RequestParser's regex may be making the keys lower case and causing any dictionary lookup to fail.

Maybe the WebSocketHttpRequest.Headers should have a custom equality comparer that would ignore the case?

Frequent refresh causes unhandled exception

Version: 0.9.6
Browser: IE10 on Windows 8

When holding Ctrl + R, the Fleck.Samples.ConsoleApp.exe will be brought to die in 1 second with following exception:

Open!
8/27/2012 9:51:16 PM [Debug] 8 bytes read
8/27/2012 9:51:16 PM [Debug] Sent 4 bytes
Close!
8/27/2012 9:51:16 PM [Debug] Swallowing ObjectDisposedException System.ObjectDis
posedException: Cannot access a disposed object.
Object name: 'System.Net.Sockets.NetworkStream'.
   at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar,
Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchron
ization)
8/27/2012 9:51:16 PM [Debug] Client Connected
8/27/2012 9:51:16 PM [Debug] 338 bytes read
8/27/2012 9:51:16 PM [Debug] Building Hybi-14 Response
8/27/2012 9:51:16 PM [Info] Failed to send. Disconnecting. System.IO.IOException
: Unable to write data to the transport connection: An existing connection was f
orcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An e
xisting connection was forcibly closed by the remote host
   at System.Net.Sockets.Socket.BeginSend(Byte[] buffer, Int32 offset, Int32 siz
e, SocketFlags socketFlags, AsyncCallback callback, Object state)
   at System.Net.Sockets.NetworkStream.BeginWrite(Byte[] buffer, Int32 offset, I
nt32 size, AsyncCallback callback, Object state)
   --- End of inner exception stack trace ---
   at System.Net.Sockets.NetworkStream.BeginWrite(Byte[] buffer, Int32 offset, I
nt32 size, AsyncCallback callback, Object state)
   at Fleck.SocketWrapper.<>c__DisplayClass1a.<>c__DisplayClass1c.<Send>b__16()
in c:\Users\Baoshan\Downloads\statianzo-Fleck-0.9.6-2-g3fea00e\statianzo-Fleck-3
fea00e\src\Fleck\SocketWrapper.cs:line 127
   at Fleck.SocketWrapper.CallbackOnError[T](Func`1 func, Action`1 error) in c:\
Users\Baoshan\Downloads\statianzo-Fleck-0.9.6-2-g3fea00e\statianzo-Fleck-3fea00e
\src\Fleck\SocketWrapper.cs:line 141
8/27/2012 9:51:16 PM [Debug] Client Connected
8/27/2012 9:51:16 PM [Error] Application Error System.IO.IOException: Unable to
read data from the transport connection: An existing connection was forcibly clo
sed by the remote host. ---> System.Net.Sockets.SocketException: An existing con
nection was forcibly closed by the remote host
   at System.Net.Sockets.Socket.BeginReceive(Byte[] buffer, Int32 offset, Int32
size, SocketFlags socketFlags, AsyncCallback callback, Object state)
   at System.Net.Sockets.NetworkStream.BeginRead(Byte[] buffer, Int32 offset, In
t32 size, AsyncCallback callback, Object state)
   --- End of inner exception stack trace ---
   at System.Net.Sockets.NetworkStream.BeginRead(Byte[] buffer, Int32 offset, In
t32 size, AsyncCallback callback, Object state)
   at Fleck.SocketWrapper.<>c__DisplayClassb.<>c__DisplayClassd.<Receive>b__7()
in c:\Users\Baoshan\Downloads\statianzo-Fleck-0.9.6-2-g3fea00e\statianzo-Fleck-3
fea00e\src\Fleck\SocketWrapper.cs:line 82
   at Fleck.SocketWrapper.CallbackOnError[T](Func`1 func, Action`1 error) in c:\
Users\Baoshan\Downloads\statianzo-Fleck-0.9.6-2-g3fea00e\statianzo-Fleck-3fea00e
\src\Fleck\SocketWrapper.cs:line 141
Close!

Expose URL in IWebSocketConnectionInfo

It would be nice to known which URL was used by the client to open the websocket, eg. ws://localhost:8181/a/b?a=1&b

Maybe this can be exposed as an IWebSocketConnectionInfo.Url property.

Can't close socket in 'OnSocketOpened'

There is a max client count which limits the total number of connected clients. If the limit of clients has been reached, all new sockets will close until another one opens up:

Socket.Start(socket =>
{
    socket.OnOpen = () => OnSocketOpened(socket);
    socket.OnClose = () => OnSocketClosed(socket);
    socket.OnMessage = message => OnSocketMessageReceived(socket, message);
});

private void OnSocketOpened(IWebSocketConnection socket)
{
    if(TotalClients == MaxClients)
    {
        socket.Close();

However invoking socket.Close() in the OnSocketOpened method throws an error. I'm not sure if I'm misusing Fleck, or if this is a bug.

Exception when refreshing the page


System.AggregateException was unhandled
  Message=A Task's exception(s) were not observed either by Waiting on the Task or accessing its Exception property. As a result, the unobserved exception was rethrown by the finalizer thread.
  Source=mscorlib
  StackTrace:
       at System.Threading.Tasks.TaskExceptionHolder.Finalize()
  InnerException: System.IO.IOException
       Message=Unable to write data to the transport connection: An established connection was aborted by the software in your host machine.
       Source=System
       StackTrace:
            at System.Net.Sockets.NetworkStream.BeginWrite(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
            at Fleck.SocketWrapper.<>c__DisplayClass16.<Send>b__12(AsyncCallback cb, Object s)
            at System.Threading.Tasks.TaskFactory.FromAsync(Func`3 beginMethod, Action`1 endMethod, Object state, TaskCreationOptions creationOptions)
            at System.Threading.Tasks.TaskFactory.FromAsync(Func`3 beginMethod, Action`1 endMethod, Object state)
            at Fleck.SocketWrapper.Send(Byte[] buffer, Action callback, Action`1 error)
            at Fleck.WebSocketConnection.SendBytes(Byte[] bytes, Action callback)
            at Fleck.WebSocketConnection.Close(Int32 code)
            at Fleck.WebSocketConnection.HandleReadError(Exception e)
            at Fleck.WebSocketConnection.HandleReadError(Exception e)
            at Fleck.SocketWrapper.<>c__DisplayClassa.<Receive>b__7(Task t)
            at System.Threading.Tasks.Task.<>c__DisplayClassb.<ContinueWith>b__a(Object obj)
            at System.Threading.Tasks.Task.InnerInvoke()
            at System.Threading.Tasks.Task.Execute()
       InnerException: System.Net.Sockets.SocketException
            Message=An established connection was aborted by the software in your host machine
            Source=System
            ErrorCode=10053
            NativeErrorCode=10053
            StackTrace:
                 at System.Net.Sockets.Socket.BeginSend(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags, AsyncCallback callback, Object state)
                 at System.Net.Sockets.NetworkStream.BeginWrite(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
            InnerException: 

Fail Connection on non-zero RSV bit

Per Spec:

RSV1, RSV2, RSV3: 1 bit each

  MUST be 0 unless an extension is negotiated that defines meanings
  for non-zero values.  If a nonzero value is received and none of
  the negotiated extensions defines the meaning of such a nonzero
  value, the receiving endpoint MUST _Fail the WebSocket
  Connection_.

Error when disconnect from client.

BROWSER: Firefox 13.0.1

CLIENT CODE:
connect: websocket = new WebSocket(uri);
disconnect: websocket.close();

SERVER ERROR:
When connect from client:
[Debug] Client Connected
[Debug] 455 bytes read
[Debug] Building Hybi-14 Response
[Debug] Sent 129 bytes

When disconnect from client (do close command or refresh browser):
[Debug] 8 bytes read
[Debug] Sent 4 bytes
[Debug] Swallowing ObjectDisposedException System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Net.Sockets.NetworkStream'.
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
at System.Threading.Tasks.TaskFactory1.FromAsyncCoreLogic(IAsyncResult iar, Func2 endMethod, TaskCompletionSource`1 tcs)

I made server by VS2010 with .NET 4.0

I try with Chrome 21. It's OK.

Certificate keys

On the home page it says:


Enabling secure connections requires two things: using the scheme wss instead of ws, and pointing Fleck to an x509 certificate containing a public and private key

var server = new WebSocketServer("wss://localhost:8431");
server.Certificate = "MyCert.cer";
server.Start(socket =>
{
//...use as normal

});

AFAIK, if a cert file should contain a private key it has to be a .pfx, not a .cer - and if it has a private key we need a password... right?

CLI has stopped working (on many F5 in broswer)

I'm run your sample server without any modifications, open your sample html file/ and i'm often press F5. and in few seconds server stopped. :(

CLI has stopped working

Problem signature:
  Problem Event Name:   CLR20r3
  Problem Signature 01: fleck.samples.consoleapp.exe
  Problem Signature 02: 1.0.0.0
  Problem Signature 03: 4ec36126
  Problem Signature 04: System
  Problem Signature 05: 4.0.0.0
  Problem Signature 06: 4db92edb
  Problem Signature 07: 2f4c
  Problem Signature 08: 23
  Problem Signature 09: System.AggregateException
  OS Version:   6.1.7601.2.1.0.256.1
  Locale ID:    1033
  Additional Information 1: 0a9e
  Additional Information 2: 0a9e372d3b4ad19135b953a78882e789
  Additional Information 3: 0a9e
  Additional Information 4: 0a9e372d3b4ad19135b953a78882e789

In console.

many exceptions like:

[Error] Application Error System.AggregateException: One or more errors occurred. ---> System.IO.IOException: Unable to read data from the
 transport connection: An established connection was aborted by the software in your host machine. ---> 

and last two exceptions:

...
11/16/2011 9:07:52 AM [Debug] Client Connected
11/16/2011 9:07:52 AM [Debug] Sent 129 bytes
Open!
11/16/2011 9:07:52 AM [Debug] 251 bytes read
11/16/2011 9:07:52 AM [Debug] Building Hybi-14 Response
11/16/2011 9:07:52 AM [Debug] Sent 129 bytes
11/16/2011 9:07:52 AM [Debug] Client Connected
Open!
11/16/2011 9:07:52 AM [Debug] 0 bytes read. Closing.
11/16/2011 9:07:52 AM [Debug] 251 bytes read
11/16/2011 9:07:52 AM [Debug] Building Hybi-14 Response
Close!
11/16/2011 9:07:52 AM [Debug] Sent 129 bytes
Open!
11/16/2011 9:07:52 AM [Debug] 0 bytes read. Closing.
Close!
11/16/2011 9:07:52 AM [Debug] Client Connected
11/16/2011 9:07:52 AM [Debug] 251 bytes read
11/16/2011 9:07:52 AM [Debug] Building Hybi-14 Response
11/16/2011 9:07:52 AM [Debug] Sent 129 bytes
Open!
11/16/2011 9:07:53 AM [Debug] 0 bytes read. Closing.
Close!
11/16/2011 9:07:53 AM [Debug] Client Connected
11/16/2011 9:07:53 AM [Debug] 251 bytes read
11/16/2011 9:07:53 AM [Debug] Building Hybi-14 Response
11/16/2011 9:07:53 AM [Debug] Sent 129 bytes
Open!
11/16/2011 9:07:53 AM [Debug] 0 bytes read. Closing.
Close!
11/16/2011 9:07:53 AM [Debug] Client Connected
11/16/2011 9:07:53 AM [Debug] 251 bytes read
11/16/2011 9:07:53 AM [Debug] Building Hybi-14 Response
11/16/2011 9:07:53 AM [Error] Application Error System.AggregateException: One or more errors occurred. ---> System.IO.IOException: Unable to read data from the
 transport connection: An established connection was aborted by the software in your host machine. ---> System.Net.Sockets.SocketException: An established conne
ction was aborted by the software in your host machine
   at System.Net.Sockets.Socket.BeginReceive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags, AsyncCallback callback, Object state)
   at System.Net.Sockets.NetworkStream.BeginRead(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
   --- End of inner exception stack trace ---
   at System.Net.Sockets.NetworkStream.BeginRead(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
   at Fleck.SocketWrapper.<>c__DisplayClassa.<Receive>b__6(AsyncCallback cb, Object s) in D:\Dropbox\Projects\Fleck\src\Fleck\SocketWrapper.cs:line 71
   at System.Threading.Tasks.TaskFactory`1.FromAsyncImpl(Func`3 beginMethod, Func`2 endMethod, Object state, TaskCreationOptions creationOptions)
   at System.Threading.Tasks.TaskFactory.FromAsync[TResult](Func`3 beginMethod, Func`2 endMethod, Object state)
   at Fleck.SocketWrapper.Receive(Byte[] buffer, Action`1 callback, Action`1 error, Int32 offset) in D:\Dropbox\Projects\Fleck\src\Fleck\SocketWrapper.cs:line 7
3
   at Fleck.WebSocketConnection.Read(List`1 data, Byte[] buffer) in D:\Dropbox\Projects\Fleck\src\Fleck\WebSocketConnection.cs:line 60
   at Fleck.WebSocketConnection.<>c__DisplayClassa.<Read>b__8(Int32 r) in D:\Dropbox\Projects\Fleck\src\Fleck\WebSocketConnection.cs:line 80
   at Fleck.SocketWrapper.<>c__DisplayClassa.<Receive>b__8(Task`1 t) in D:\Dropbox\Projects\Fleck\src\Fleck\SocketWrapper.cs:line 74
   at System.Threading.Tasks.Task`1.<>c__DisplayClass17.<ContinueWith>b__16(Object obj)
   at System.Threading.Tasks.Task.InnerInvoke()
   at System.Threading.Tasks.Task.Execute()
   --- End of inner exception stack trace ---
---> (Inner Exception #0) System.IO.IOException: Unable to read data from the transport connection: An established connection was aborted by the software in you
r host machine. ---> System.Net.Sockets.SocketException: An established connection was aborted by the software in your host machine
   at System.Net.Sockets.Socket.BeginReceive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags, AsyncCallback callback, Object state)
   at System.Net.Sockets.NetworkStream.BeginRead(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
   --- End of inner exception stack trace ---
   at System.Net.Sockets.NetworkStream.BeginRead(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
   at Fleck.SocketWrapper.<>c__DisplayClassa.<Receive>b__6(AsyncCallback cb, Object s) in D:\Dropbox\Projects\Fleck\src\Fleck\SocketWrapper.cs:line 71
   at System.Threading.Tasks.TaskFactory`1.FromAsyncImpl(Func`3 beginMethod, Func`2 endMethod, Object state, TaskCreationOptions creationOptions)
   at System.Threading.Tasks.TaskFactory.FromAsync[TResult](Func`3 beginMethod, Func`2 endMethod, Object state)
   at Fleck.SocketWrapper.Receive(Byte[] buffer, Action`1 callback, Action`1 error, Int32 offset) in D:\Dropbox\Projects\Fleck\src\Fleck\SocketWrapper.cs:line 7
3
   at Fleck.WebSocketConnection.Read(List`1 data, Byte[] buffer) in D:\Dropbox\Projects\Fleck\src\Fleck\WebSocketConnection.cs:line 60
   at Fleck.WebSocketConnection.<>c__DisplayClassa.<Read>b__8(Int32 r) in D:\Dropbox\Projects\Fleck\src\Fleck\WebSocketConnection.cs:line 80
   at Fleck.SocketWrapper.<>c__DisplayClassa.<Receive>b__8(Task`1 t) in D:\Dropbox\Projects\Fleck\src\Fleck\SocketWrapper.cs:line 74
   at System.Threading.Tasks.Task`1.<>c__DisplayClass17.<ContinueWith>b__16(Object obj)
   at System.Threading.Tasks.Task.InnerInvoke()
   at System.Threading.Tasks.Task.Execute()<---

11/16/2011 9:07:53 AM [Debug] Sent 129 bytes
Open!
11/16/2011 9:07:53 AM [Debug] Client Connected
11/16/2011 9:07:53 AM [Debug] 251 bytes read
11/16/2011 9:07:53 AM [Debug] Building Hybi-14 Response
11/16/2011 9:07:53 AM [Debug] Sent 129 bytes
Open!
11/16/2011 9:07:53 AM [Debug] 0 bytes read. Closing.
Close!
11/16/2011 9:07:53 AM [Debug] Client Connected

Unhandled Exception: System.AggregateException: A Task's exception(s) were not observed either by Waiting on the Task or accessing its Exception property. As a
result, the unobserved exception was rethrown by the finalizer thread. ---> System.IO.IOException: Unable to write data to the transport connection: An establis
hed connection was aborted by the software in your host machine. ---> System.Net.Sockets.SocketException: An established connection was aborted by the software
in your host machine
   at System.Net.Sockets.Socket.BeginSend(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags, AsyncCallback callback, Object state)
   at System.Net.Sockets.NetworkStream.BeginWrite(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
   --- End of inner exception stack trace ---
   at System.Net.Sockets.NetworkStream.BeginWrite(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
   at Fleck.SocketWrapper.<>c__DisplayClass16.<Send>b__12(AsyncCallback cb, Object s) in D:\Dropbox\Projects\Fleck\src\Fleck\SocketWrapper.cs:line 111
   at System.Threading.Tasks.TaskFactory.FromAsync(Func`3 beginMethod, Action`1 endMethod, Object state, TaskCreationOptions creationOptions)
   at System.Threading.Tasks.TaskFactory.FromAsync(Func`3 beginMethod, Action`1 endMethod, Object state)
   at Fleck.SocketWrapper.Send(Byte[] buffer, Action callback, Action`1 error) in D:\Dropbox\Projects\Fleck\src\Fleck\SocketWrapper.cs:line 113
   at Fleck.WebSocketConnection.SendBytes(Byte[] bytes, Action callback) in D:\Dropbox\Projects\Fleck\src\Fleck\WebSocketConnection.cs:line 104
   at Fleck.WebSocketConnection.Close(Int32 code) in D:\Dropbox\Projects\Fleck\src\Fleck\WebSocketConnection.cs:line 148
   at Fleck.WebSocketConnection.<Read>b__9(Exception e) in D:\Dropbox\Projects\Fleck\src\Fleck\WebSocketConnection.cs:line 97
   at Fleck.SocketWrapper.<>c__DisplayClassa.<Receive>b__7(Task t) in D:\Dropbox\Projects\Fleck\src\Fleck\SocketWrapper.cs:line 75
   at System.Threading.Tasks.Task.<>c__DisplayClassb.<ContinueWith>b__a(Object obj)
   at System.Threading.Tasks.Task.InnerInvoke()
   at System.Threading.Tasks.Task.Execute()
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.TaskExceptionHolder.Finalize()
11/16/2011 9:07:53 AM [Debug] 251 bytes read
11/16/2011 9:07:53 AM [Debug] Building Hybi-14 Response
11/16/2011 9:07:53 AM [Debug] Sent 129 bytes
11/16/2011 9:07:53 AM [Debug] 0 bytes read. Closing.
Close!
11/16/2011 9:07:53 AM [Debug] Client Connected
Open!
11/16/2011 9:07:53 AM [Debug] 251 bytes read
11/16/2011 9:07:53 AM [Debug] Building Hybi-14 Response
11/16/2011 9:07:53 AM [Debug] Sent 129 bytes
Open!
11/16/2011 9:07:53 AM [Debug] 0 bytes read. Closing.
Close!
11/16/2011 9:07:53 AM [Debug] Client Connected
11/16/2011 9:07:53 AM [Debug] 251 bytes read
11/16/2011 9:07:53 AM [Debug] Building Hybi-14 Response
11/16/2011 9:07:53 AM [Debug] Sent 129 bytes
Open!
11/16/2011 9:07:53 AM [Debug] 0 bytes read. Closing.
Close!
11/16/2011 9:07:53 AM [Debug] Client Connected
11/16/2011 9:07:53 AM [Debug] 251 bytes read
11/16/2011 9:07:53 AM [Debug] Building Hybi-14 Response
11/16/2011 9:07:53 AM [Debug] Sent 129 bytes
Open!
11/16/2011 9:07:53 AM [Debug] 0 bytes read. Closing.
Close!
11/16/2011 9:07:53 AM [Debug] Client Connected
11/16/2011 9:07:53 AM [Debug] 251 bytes read
11/16/2011 9:07:53 AM [Debug] Building Hybi-14 Response
11/16/2011 9:07:53 AM [Debug] Sent 129 bytes
Open!

SSL/TLS is not working

Using the sample provided, I made some changes so that it uses SSL. However when I run the program I get the following error:

5/22/2012 11:58:29 PM [Info] Server started at wss://localhost:8181
5/22/2012 11:58:33 PM [Debug] Client Connected
5/22/2012 11:58:33 PM [Debug] Authenticating Secure Connection

<At this point, Chrome hangs at 100%. When I close Chrome, the following is displayed.

5/22/2012 11:59:28 PM [Error] Application Error System.IO.IOException: Unable to
read data from the transport connection: An existing connection was forcibly cl
osed by the remote host. ---> System.Net.Sockets.SocketException: An existing co
nnection was forcibly closed by the remote host
at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
--- End of inner exception stack trace ---
at System.Net.Security._SslStream.EndRead(IAsyncResult asyncResult)
at System.Net.Security.SslStream.EndRead(IAsyncResult asyncResult)
at System.Threading.Tasks.TaskFactory1.FromAsyncCoreLogic(IAsyncResult iar, Func2 endMethod, TaskCompletionSource`1 tcs)

Below is my code:

    static void Main()
    {
        FleckLog.Level = LogLevel.Debug;
        var allSockets = new List<IWebSocketConnection>();
        var server = new WebSocketServer("wss://localhost:8181");
        server.Certificate = new X509Certificate2(@"c:\astroslocal\ssl\cosmos2.pfx", "c0sm0s");

        server.Start(socket =>
            {
                socket.OnOpen = () =>
                    {
                        Console.WriteLine("Open!");
                        allSockets.Add(socket);
                    };
                socket.OnClose = () =>
                    {
                        Console.WriteLine("Close!");
                        allSockets.Remove(socket);
                    };
                socket.OnMessage = message =>
                    {
                        Console.WriteLine(message);
                        allSockets.ToList().ForEach(s => s.Send("Echo: " + message));
                    };
            });


        var input = Console.ReadLine();
        while (input != "exit")
        {
            foreach (var socket in allSockets.ToList())
            {
                socket.Send(input);
            }
            input = Console.ReadLine();
        }

    }

Connecting to Fleck using C# client

Hi,

I implemented the websocket server using Fleck, and when sending messages from a web page using javascript it works perfectly. However, I need to be able to send messages from a C# client. I have tried using both Alchemy websockets and Websocket4net, but both of them fail to send messages to the server. Any idea what it could be?

WebSocketServer needs a Stop() method

Either that or I don't understand the proper way to shut down an instance. I have tried calling Close() on all of the IWebSocketConnection objects, and then calling server.Dispose(), but I can't seem to make that work. Any suggestions?

Invoke start callback after request is parsed

I have a scenario where I need the connection info in the start callback. Right now connection info is always null since the thing is invoked.

var wss = new WebSocketServer("ws://localhost:8181");
wss.Start(socket =>
{
    if (socket.ConnectionInfo == null)
    {
        Console.WriteLine("Connection info is null here");
    }
});

The above code will always print "Connection info is null here". I've fixed this in my fork but haven't spent much time running tests as I wanted to run it by you first. The change is pretty small:

davidfowl@2c391ec

Let me know if you need me to do anything else, I'll be happy to send a pull request.

Secure Socket Async problem

H I I use Fleck in my app when I run it throw that Error.

System.NotSupportedException: The BeginWrite method cannot be called when another write operation is pending.
at System.Net.Security._SslStream.ProcessWrite(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security._SslStream.BeginWrite(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback asyncCallback, Object asyncState)
at System.Net.Security.SslStream.BeginWrite(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback asyncCallback, Object asyncState)
at Game.Base.SocketWrapper.<>c__DisplayClass16.b__12(AsyncCallback cb, Object s) in ####################################################\Frame\SocketWrapper.cs:line 111
at System.Threading.Tasks.TaskFactory.FromAsync(Func3 beginMethod, Action1 endMethod, Object state, TaskCreationOptions creationOptions)
at System.Threading.Tasks.TaskFactory.FromAsync(Func3 beginMethod, Action1 endMethod, Object state)
at Game.Base.SocketWrapper.Send(Byte[] buffer, Action callback, Action`1 error) in

##############################################\Frame\SocketWrapper.cs:line 113

at Game.Base.Frame.WebSocketConnection.SendBytes(Byte[] bytes, Action callback) in ####################################################\Frame\WebSocketConnection.cs:line 116

RequestParser.cs regex isn't validating blank header values

I have the following message coming in from a Flash socket:

GET /api/authenticate? HTTP/1.1
Host: win.omega.gloss.io
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: ET02NCZpCVQiW3k4TkNZOQ==
Origin: http://mac.gloss.io
Sec-WebSocket-Version: 13
Cookie:

The regex in RequestParser.cs is choking on the Cookie: because it's blank. Sorry but I don't know enough about regex to offer a solution.

Provide a way to set certificate through standard Windows means

There should be a way to set the certificate through the Windows certificate store API.

Something like this:

X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certificates = store.Certificates.Find(
X509FindType.FindByThumbprint, thumbprint, true);

server.Certificate = certificates[0];

Support Binary Messages

Currently, incoming binary messages are piped as UTF messages. Let's fix that and add send/receive support for binary.

Hybi14 Pegs CPU

When a client disconnects, the Socket (oddly) doesn't report as closed. This winds up in a continuous loop reading 0 bytes, using 100% cpu. Closing on 0 bytes should fix this.

send timeout

is it possible to set a timeout for the IWebSocketConnection.Send() method or to build it in a future release?

SocketException on Receiver.cs line 39

Hi

Fleck is really nice - great work! This is by far the cleanest WebSockets implementation I've seen on .NET yet. I've tried it out in a number of situations using Chrome and Mobile Safari and it worked great.

However, sometimes my server app shuts down with an unhandled exception when a remote client closes the connection. Here's the stack trace:

Unhandled Exception: System.Net.Sockets.SocketException: An existing connection
was forcibly closed by the remote host
at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)
at Fleck.Receiver.<>c__DisplayClass1.b__0(IAsyncResult r) in C:...\statianzo-Fleck-774fedc\statianz
o-Fleck-774fedc\src\Fleck\Receiver.cs:line 39
at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
at System.Net.ContextAwareResult.CompleteCallback(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, C
ontextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, C
ontextCallback callback, Object state)
at System.Net.ContextAwareResult.Complete(IntPtr userToken)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr u
serToken)
at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32
errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32
errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)

User authentication

What is your vision around authentication users? Like basic auth over SSL in the initial request...

exception

I have seen following exception frequently:

System.NullReferenceException was unhandled by user code
HResult=-2147467261
Message=Object reference not set to an instance of an object.
Source=mscorlib
StackTrace:
at System.Threading.Tasks.TaskFactory1.FromAsyncImpl(Func3 beginMethod, Func2 endFunction, Action1 endAction, Object state, TaskCreationOptions creationOptions)
at System.Threading.Tasks.TaskFactory.FromAsync(Func3 beginMethod, Action1 endMethod, Object state)
at Fleck.SocketWrapper.Send(Byte[] buffer, Action callback, Action1 error) in c:\projects\Code\Fleck\SocketWrapper.cs:line 129 at Fleck.WebSocketConnection.SendBytes(Byte[] bytes, Action callback) in c:\projects\Code\Fleck\WebSocketConnection.cs:line 158 at Fleck.WebSocketConnection.Close(Int32 code) in c:\projects\Code\Fleck\WebSocketConnection.cs:line 92 at Fleck.WebSocketConnection.HandleReadError(Exception e) in c:\projects\Code\Fleck\WebSocketConnection.cs:line 152 at Fleck.WebSocketConnection.HandleReadError(Exception e) in c:\projects\Code\Fleck\WebSocketConnection.cs:line 129 at Fleck.SocketWrapper.<>c__DisplayClassb.<Receive>b__a(Task1 t) in c:\projects\Code\Fleck\SocketWrapper.cs:line 87
at System.Threading.Tasks.ContinuationTaskFromResultTask`1.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
InnerException:

I'm using Chrome with the reconnecting websocket code (https://github.com/joewalnes/reconnecting-websocket).

Flash Cross-Domain Policy Server

Adding this because it was mentioned on my blog in a comment.

Adding a cross-domain policy server would allow for Flash websocket polyfills to work with Fleck.

Documentation Required

There needs to be XML documentation for this project so that people have a better understanding of how to use the library.

iOS & Android

Before I try to rewrite my server code and test Fleck... ;)
Did you ever test Fleck with iOS and/or Android web browser clients? I tried another C# WebSockets server yesterday and this one failed.

Thanks!

Error when closing the socket on the client

When we close the socket on the client/browse the following exception is raised inside Fleck:

Error: System.AggregateException: One or more errors occurred. ---> System.Objec
tDisposedException: Cannot access a disposed object.
Object name: 'System.Net.Sockets.NetworkStream'.
   at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar,
Func`2 endMethod, TaskCompletionSource`1 tcs)
   --- End of inner exception stack trace ---
---> (Inner Exception #0) System.ObjectDisposedException: Cannot access a dispos
ed object.
Object name: 'System.Net.Sockets.NetworkStream'.
   at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar,
Func`2 endMethod, TaskCompletionSource`1 tcs)<---

16-10-2011 22:34:29 [Error] Application Error System.AggregateException: One or
more errors occurred. ---> System.ObjectDisposedException: Cannot access a dispo
sed object.
Object name: 'System.Net.Sockets.NetworkStream'.
   at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar,
Func`2 endMethod, TaskCompletionSource`1 tcs)
   --- End of inner exception stack trace ---
---> (Inner Exception #0) System.ObjectDisposedException: Cannot access a dispos
ed object.
Object name: 'System.Net.Sockets.NetworkStream'.
   at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar,
Func`2 endMethod, TaskCompletionSource`1 tcs)<---

DataFrame does not match spec.

The DataFrame does not match the websocket spec.

This leads to possible loss of data if messages are sent rapidly from the client.

For example:

for(var i = 0; i < 10; i++){ws.send('hello: ' + i);}

May wind up missing some of the hello: n messages.

Crash when browser disappears in the middle of a session

This may be a duplicate issue, possibly related to #47.

I have a demo server running on a public host, and occasionally a browser crash will kill it. I'm still looking into the browser crash (I'm working with WebRTC in Chrome, and it can sometimes be a little unstable), but I need to know what's going on with Fleck.

I notice in SocketWrapper.Send there's the note: "despite the try-catch already here, this crashed with an IOException when a client browser disappeared in the middle of a connection." That seems to describe my situation. Is this something actively being investigated, and is there something I can do about it in the meantime?

Also, I've definitely seen my server crash on a browser refresh, perhaps like in issue 47.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.