I'm writing a simple reverse proxy which will need to handle http GETs and POSTs and WebSocket connections. Numbers of simultaneous clients will be low so I had hoped to use HttpListener. I'm struggling to see how to use that to proxy a WebSocket connection though.
I think responses have to be sent via HttpListenerResponse. For GETs and POSTs this is easy. For WebSockets I'd need to send handshake data then keep the connection open to send further messages from the server being proxyed. The only way I can see to send data using HttpListenerResponse is to call Close(), presumably preventing further use of the underlying socket.
Similar issues presumably exist with trying to use HttpListenerRequest to receive later websocket messages from the client.
Am I missing something here or is there no way to use HttpListener with websockets?
Seems there is no way with HttpListener right now. You have to wait .NET 4.5.
Related
I am working on an C# Asp.NET Core app where clients will connect via a JavaScript WebSocket to the server and the server itself will be the only thing that can send messages to the connected clients.
The clients will not be sending messages back to the server and if they manage to send a message to the server by manually doing so in any browser console, the server will just ignore them.
This is a sample of the C# code I am using to send messages to all connected clients:
foreach(WebSocket webSocket in WebsocketHandler.WebSocketClients.Values)
{
await webSocket.SendAsync(...);
}
Since I am not expecting clients to send messages back to the server (since this is supposed to be a one-way message flow), is a subsequent call to:
await webSocket.ReceiveAsync(...);
immediately after a call to "SendAysnc()" required at all? Are their downsides/consequences to not calling "ReceiveAsync()" after calling "SendAsync()"?
I could not find anything in the documentation from MS that says it is required to call "ReceiveAsync" after calling "SendAsync()" (though most online examples do) and both methods (according to MS documentation) state that "This operation will not block."
My primary concern here with this is whether or not continuously only sending messages and not receiving anything back may either cause a memory leak from many "SendAsync()" calls piling up because it expects some "response" back or the server disconnecting a client(s) because no message is being sent back from the other side of the communication channel and the server thinks the client has dropped.
Regards.
You need to call ReceiveAsync so you can detect when the websocket closes so you can complete the close handshake. Generally when using websockets directly, you'll have 2 async loops running in parallel, the receive loop and send loop (or you can hand off the socket to send like you are doing). You also need to make sure the request that did the websocket upgrade keeps running so that the connection doesn't get closed and in your scenario, you can use the receive loop for that purpose.
I have a requirement to return streamed response from WCF service.
The client would call GET on WCF REST URI and the server would send XML response when available. If no response is available, server would send a dummy XML response every few seconds to keep the connection alive.
I know this should ideally be done using Signal R (WebSockets) but I would like to know if there is a way to achieve this in WCF (without using Signal R).
I don't have to return large data, I would like to send intermittent small sized XML data.
Let me know if someone has achieved something like this with WCF REST?
I am not sure how flexible you are by using WebAPI, sorry if its not what you want, but I came across this code below which is basically an api controller that pushes data back to the client on a continuous basis as HTTP response..
The client is basically a HttpClient which connects to a Uri address issuing a GET HttpRequestMessage. The message is sent with SendAsync and the stream is received as response.Content.ReadAsStreamAsync()...
Here is the link: http://aspnet.codeplex.com/SourceControl/changeset/view/bb167f0b0013#Samples/Net4/CS/WebApi/PushContentControllerSample/PushContentController/Controllers/PushContentController.cs
The best way to create a persistent connection between server and client is to use WebSockets.
WCF can use WebSockets via the NetHttpBinding.
Once configured, you can force communication to always be over WebSockets via:
transportUsage=Always
Since you have a persistent connection, you will need to use callbacks to manage application flow when data is sent across.
There's also a detailed article here describing a few different ways to create WebSocket connections in .NET (without SignalR).
Create a WCF Service that Communicates over WebSockets
I'm working on a game that depends on the standard System.Net.Sockets library for networking. What's the most efficient and standardized "system" I should use? Should the client send data requests every set amount of seconds, when a certain event happens? My other question, is a port forward required for a client to listen and receive data? How is this done, is there another socket created specifically for listening only on the client? How can I send messages and listen on the same socket on the client? I'm having a difficult time grasping the concept of networking, I started messing with it two days ago.
Should the client send data requests every set amount of seconds, when a certain event happens?
No. Send your message as soon as you can. The socket stack has algorithms that determine when data is actually sent. For instance the Nagle algorithm.
However, if you send a LOT of messages it can be beneficial to enqueue everything in the same socket method call. However, you need to send several thousand of messages per client and second for that to give you any benefit.
My other question, is a port forward required for a client to listen and receive data?
No. Once a socket connection have been established it's bidirectional. i.e. both end points and send and receive information without screwing something up for the other end point.
But to achieve that you typically have to use asynchronous operations so that you can keep receiving all the time.
How is this done, is there another socket created specifically for listening only on the client?
The server has a dedicated socket (a listener) which only purpose is to accept client sockets. When the listener have accepted a new connection from a remote end point you get a new socket object which represents the connection to the newly connected endpoint.
How can I send messages and listen on the same socket on the client?
The easiest way is to use asynchronous receives and blocking sends.
If you do not want to take care of everything by yourself, you can try my Apache licensed library http://sharpmessaging.net.
Creating a stable, high quality server will require you to have a wealth of knowledge on networking and managing your objects.
I highly recommend you start with something smaller before attempting to create your own server from scratch, or at the very least play around with a server for a different game that's already made, attempt to improve upon it or add new features.
That being said, there are a few ways you can setup the server, if you plan on having more than a couple of clients you don't generally want them to all send data whenever they feel like it as this can bog down the server, you want to structure it in such a way that the client sends as little data as possible on a scheduled basis and the server can request more when its ready. How that's setup and structured is up to you.
A server generally has to have a port forwarded on the router in order for requests to make it to the server from the internet, and here is why. When your computer makes a connection to a website (stackoverflow for example) it sends out a request on a random port, the router remembers the port that you sent out on and remembers who sent it (you), when the server sends the information you requested back the router knows you wanted that data and sends it back to you, in the case of RUNNING a server there is no outbound request to a client (Jack for example), so the router doesnt know where jacks request is supposed to go. By adding a port forwarding rule in the router your saying that all information passed to port 25565 (for example) is supposed to go to your server.
Clients generally do not need to forward ports because they are only making outbound requests and receiving data.
Server Starts, server starts listening on port 25565
Client starts, client connects to server on port 25565 and initiates a connection
Server responds to client on whatever port the client used to connect (this is done behind the scenes in sockets)
Communication continues from here.
I do not quite understand how exactly persistent connections work.
So the keepalive property is set by default and this should keep my connection open, as far as I understand it.
So right now I am sending my data via a POST on an HTTPWebRequest.
But I do this everytime I send something to the recipient.
So it is like this:
POST data from client to server, response to the post is returned.
But next i just send another POST, instead of using the connection I already opened. So I feel like I am sending more than I actually have to.
Can't I just open the connection once and then continue communication via this connection?
I am sorry for my poor understanding of this subject, but this is the first time I really work with network protocols.
Thanks in advance
Daniel
KeepAlive was added to HTTP protocol to improve server-side performance.
HTTP is generally a stateless protocol. All state is preserved as cookies or server's session. If KeepAlive is set to true, client and the server could potentially keep their underlying TCP Connection alive.
Usually a time-out set for KeepAlive so that if client did not make any other request, this connection is closed.
This feature is usually implemented differently across different platforms, for example I have seen issues with Java implementation where they do not respect the timeout and server closes the connection so client's attempt to connect again fails since it assumes connection is still open.
See RFC document here.
You can reuse the connection IF the server supports it.... including any proxies in between you and the server. Which is where it sometimes falls down. It was tacked on to HTTP 1.0 and officially added in 1.1.
Basically, your client asks "may I keep this connection alive" with a special header, then if the server supports it, it replies saying "yes" and the client can then send more requests on the same socket.
Your client code also has to support this ability. .Net should be fine.
We have a custom chat application(c#) which uses TCPClient. We are having problem on clients who are behind Firewall or proxy. We know that these client can browse the internet without a problem so we decided to change our TCPClient application so that It uses HTTP messages to communicate.
Will it be enough just to wrap our text massages with standard HTML tags and HTTP headers? We need a long lasting connection. Does keep-alive have a limit? Do firewalls or proxies have time limits for "alive" connections.
You would need to change your protocol, probably pretty significantly. There's no guarantee that a proxy is going to use the same TCP connection for subsequent HTTP requests, it has the freedom to close any connection after receiving a message from the server, and they generally will after only a few idle seconds.
Unless your protocol can work stateless, then it isn't going to work over HTTP through a proxy.