Socket.IO
Socket.IO is a real-time application framework based on Node.js, which has a wide range of applications including instant messaging, notification and message push, real-time analysis and other scenarios.
WebSocket originated from the growing demand for real-time communication in web development, compared with http-based polling, which greatly saves network bandwidth and reduces server performance consumption. Socket.IO supports both websockets and polling. The data transmission method is compatible with the browser and does not support the communication requirements under the WebSocket scenario.
The framework provides the egg-socket.io plugin with the following development rules added:
- namespace: define the namespace by means of configuration - middleware: establish / disconnect every socket connection, preprocess every message / data transfer - controller: response socket.io event - router: unify the processing configuration of socket.io event and frame routing
# install egg-socket.io
# Installation
$ npm i egg-socket.io --save |
Enable the plugin:
// {app_root} /config/plugin.js |
# Configuration
// {app_root} / config / config. $ {env} .js |
Namespaces are
/
and/ example
, notexample
# uws
Egg's socket is using ws
, uws is deprecated due to some reasons.
If you insist using uws instead of the default ws
, you can config like this:
// {app_root} / config / config. $ {env} .js |
# redis
egg-socket.io has built-in redis support via socket.io-redis
. In cluster mode, the use of redis can make it relatively simple to achieve information sharing of clients/rooms and so on
// {app_root} / config / config. $ {env} .js |
When
redis
is turned on, the program tries to connect to the redis server at startup Hereredis
is only used to store connection instance information, see # server.adapter
Note:
If the project also uses the egg-redis
, please configure it separately. Do not share it.
# Deployment
If the framework is started in cluster mode, the socket.io protocol implementation needs sticky feature support, otherwise it will not work in multi-process mode.
Due to the design of socket.io, a multi-process server must be in the sticky working mode. As a result, you need the need to pass parameter --sticky
when starting the cluster.
Modify the npm scripts
script inpackage.json
:
{ |
Nginx configuration
location / { |
# Using egg-socket.io
The directory structure of project which has enabled the egg-socket.io is as follows:
chat |
Note: The corresponding files are in the app / io directory
# Middleware
Middleware has the following two scenarios:
- Connection
- Packet
It is configured in each namespace, respectively, according to the scenarios given above.
Note:
If we enable the framework middleware, you will find the following directory in the project:
app / middleware
: framework middlewareapp / io / middleware
: plugin middleware
the difference:
- Framework middleware is based on http model design to handle http requests.
- Plugin middleware based socket model design, processing socket.io request.
Although the framework tries to unify the style through plugins, it is important to note that their usage scenarios are different. For details, please see: # 1416
# Connection
Fires when each client connects or quits. Therefore, we usually perform authorization authentication at this step, and deal with the failed clients.
// {app_root} /app/io/middleware/connection.js |
Kick out the user example:
const tick = (id, msg) => { |
At the same time, the current connection can also be simple to deal with:
// {app_root} /app/io/middleware/connection.js |
# Packet
Acts on each data packet (each message). In the production environment, it is usually used to preprocess messages, or it is used to decrypt encrypted messages.
// {app_root} /app/io/middleware/packet.js |
# Controller
A controller deals with the events sent by the client. Since it inherits the egg.controller
, it has the following member objects:
- ctx
- app
- service
- config
- logger
For details, refer to the [Controller] (../ basics / controller.md) documentation
// {app_root} /app/io/controller/default.js |
# Router
Routing is responsible for passing various events received by the socket to the corresponding controllers.
// {app_root} /app/router.js |
Note:
Nsp has the following system events:
disconnecting
doing the disconnectdisconnect
connection has disconnected.error
Error occurred
# Namespace/Room
# Namespace (nsp)
The namespace is usually meant to be assigned to different access points or paths. If the client does not specify a nsp, it is assigned to "/" by default.
In socket.io we use the of
to divide the namespace; given that nsp is usually pre-defined and relatively fixed, the framework encapsulates it and uses configuration to partition different namespaces.
// socket.io |
# Room
Room exists in nsp and is added or left by the join/leave method; the method used in the framework is the same;
Const room = 'default_room'; |
Note: Each socket connection will have a random and unpredictable unique id Socket#id
and will automatically be added to the room named after this id
# Examples
Here we use egg-socket.io to do a small example which supports p2p chat
# Client
The UI-related content is not rewritten. It can be called via window.socket
// browser |
# WeChat Applets
The API provided by the WeChat applet is WebSocket, and socket.io is the upper encapsulation of Websocket. Therefore, we cannot directly use the API connection of the applet. You can use something like [wxapp-socket-io] (https://github.com/wxsocketio /wxapp-socket-io) to adapt to the library.
The sample code is as follows:
// Small program-side sample code |
# Server
The following is part of the demo code and explains the role of each method:
# Config
// {app_root}/config/config.${env}.js |
# Helper
Framework extensions for encapsulating data formats
// {app_root}/app/extend/helper.js |
Format:
{ |
# Middleware
egg-socket.io middleware handles socket connection handling
// {app_root}/app/io/middleware/auth.js |
# Controller
Data exchange of P2P communication is through exchange
// {app_root}/app/io/controller/nsp.js |
# Router
// {app_root}/app/router.js |
Open two tab pages and call up the console:
socket.emit('exchange', { |