I have a some questions in understanding websocket communication. AFAIU, in client side, it works like this:
- From client, a new Socket handler is created using "new WebSocket('ws://blahblah')"
- Then using onOpen() method its known that we are connected to WS server
- Using onMessage() metthod, its known that a message has been received from WS Server
- OnClose() method dictates the socket connection is closed
So from client perspective its clear.
But from the server perspective how the flow goes (as above for client) and what is exactly mean by a websocket server process and what is exactly when we mean the communication happens on TCP and how do we check that (my aplologies if the question is very basic)
Can somebody please explain.
Thanks in advannce
How do WebSocket servers work?
A WebSocket is a persistent connection between a client and server. WebSockets provide a bidirectional, full-duplex communications channel that operates over HTTP through a single TCP/IP socket connection. At its core, the WebSocket protocol facilitates message passing between a client and server.
Can WebSocket be client to server?
◉ WebSocket (inbuilt in HTML5)WebSocket is a standard protocol for two-way data transfer between a client and a server. The webSocket protocol is built on TCP, NOT running on over HTTP protocol.
How many WebSockets can a server handle?
By default, a single server can handle 65,536 socket connections just because it's the max number of TCP ports available.
How do I run a WebSocket on a server?
A simple example. To open a websocket connection, we need to create new WebSocket using the special protocol ws in the url: let socket = new WebSocket("ws://javascript.info"); There's also encrypted wss:// protocol.
On server side it is really depends on implementation, language and API of websockets library or you own implementation you use.
This description is actual only for RAW implementation of WebSockets and is not based on use of any libraries to work with WebSockets protocol.
Libraries, such as jWebSockets (Java), SignalR, socket.io and others will have absolutely another processes to work with WebSockets.
If we are talking about raw implementation on raw sockets, so process is like that:
- Create server side TCP socket, bind to specific port and listen it, and then put on accepting state. Accepting can be blocking or non-blocking. I use .Net, and did asynchronous accepting, that way it will trigger method every time there is connection to server.
1b. Client called through JS: new WebSocket(...);
- After accepted new socket, it have to start receiving data. TCP protocol is stream based, but not message based.
- WebSockets protocol requires HTTP handshake for WebSockets to be done before you can communicate. So straight away after accepting new socket, you start receving data, and first what you will receive is handshake data - some lines of text.
- Proceed through handshake process. It means read handshake data, and generate on server side response handshake data and send it over to WebSocket.
4b. If handshake data will be validated and verified by client side (browser), you will get callback "onopen", otherwise you will might get "onerror" and "onclose" after it.
- After handshake is done, you can receive and send messages. Messages are dataframed (not raw) based on WebSockets protocol. And WebSockets are MESSAGE based protocol. So you have to make sure you read specific amount of message data before you proceed data for logical processing.
- For receiving data on server side, if you use own implementation you have to implement reading from TCP socket stream. To do so, you will always want to read only 2 bytes, if there will be some (2 bytes) - this is header data, decode it based on protocol data framing specification, and keep reading rest of data to find out if there is masking then read masking bytes, and length. It is all in header. But header can be slightly different length. That is why you have to read only 2 bytes first, and then some after. After you get length, you have to read exactly this length of bytes from TCP socket stream. After all read, and actual data is demasked (if masking was enabled, for my experience it is always enabled), after that, you can put socket on reading some other data from the beginning. Do not start reading new message before finished reading current one.
- After message is read and demasked, you will have raw data, in most cases it is just string that you sent from client using "socket.send("...");".
- To send data, you have to take raw string data, then get bytes of string using UTF8 encoding, and after cover it with data framing, so it is inverse as reading, only difference is that you should not do masking. So from server to client data is not masked.
- After you made binary and sent it, if everything is right you might receive on client side "onmessage" with data you sent.
Client will never receive part of data, or unordered data. It will always receive packets in order you sent, and always as you sent.
Server might receive data partially based on low level TCP layer processes. But will receive always ordered.
This protocol is Reliable and Ordered.
Most popular specification of WebSockets protocol RFC 6455, bear in mind that iOS uses another specification and they might not be cross-compatible what means that you need to create another handshake functionality and data framing specifically for different protocol implementations.