WebSocket 的产生源于 Web 开发中日益增长的实时通信需求,对比基于 http 的轮询方式,它大大节省了网络带宽,同时也降低了服务器的性能消耗; socket.io 支持 websocket、polling 两种数据传输方式以兼容浏览器不支持 WebSocket 场景下的通信需求。
 
框架提供了 egg-socket.io 插件,增加了以下开发规约:
namespace: 通过配置的方式定义 namespace(命名空间)
middleware: 对每一次 socket 连接的建立/断开、每一次消息/数据传递进行预处理
controller: 响应 socket.io 的 event 事件
router: 统一了 socket.io 的 event 与 框架路由的处理配置方式
 
安装
$ npm i egg-socket.io --save

开启插件:config/plugin.js

exports.io = {
enable: true,
package: 'egg-socket.io',
};

配置插件config/config.default.js

/ 和 new2 属于不同的命名空间 即如果你有两个业务用到了socket,可以分别用不同的命名空间去管理,如果只用到一个写一个及可

exports.io = {
init: { }, // passed to engine.io
namespace: {
'/': {
connectionMiddleware: [],
packetMiddleware: [],
},
'/news': {
connectionMiddleware: [],
packetMiddleware: [],
},
},
};

router\io.js 路由可以分别为不同的命名空间配置路由

of 来划分命名空间
io.of('/').route('chat', io.controller.chat.index);
io.of('/').route('message', io.controller.chat.message);
io.of('/').route('user', io.controller.chat.online); io.of('/news').route('news', io.controller.news.index);

在生产环境下Nginx 配置

location / {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:7001; # http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_bind
# proxy_bind $remote_addr transparent;
}
开启 egg-socket.io 的项目目录结构如下:
chat
├── app
│ ├── extend
│ │ └── helper.js
│ ├── io
│ │ ├── controller
│ │ │ └── default.js
│ │ └── middleware
│ │ ├── connection.js
│ │ └── packet.js
│ └── router.js
├── config
└── package.json

对应的文件都在io下

app/io

配置socket的中间件在 app/io/middleware 下    新建auth.js

在每一个客户端连接或者退出时发生作用,故而我们通常在这一步进行授权认证,对认证失败的客户端做出相应的处理

/**
* Created by bear on 2018/2/12.
*/
const PREFIX = 'room'; //定义房间号 module.exports = app => {
return async (ctx, next) => {
const { app, socket, logger, helper } = ctx;
const id = socket.id;
const nsp = app.io.of('/');
const query = socket.handshake.query; // 用户信息
const { room, userId } = query; //获取socket链接传过来的参数
const rooms = [ room ]; console.log(room, userId); const tick = (id, msg) => {
logger.debug('#tick', id, msg);
// 踢出用户前发送消息
socket.emit(id, helper.parseMsg('deny', msg));
// 调用 adapter 方法踢出用户,客户端触发 disconnect 事件
nsp.adapter.remoteDisconnect(id, true, err => {
logger.error(err);
});
};
// 检查房间是否存在,不存在则踢出用户
// 备注:此处 app.redis 与插件无关,可用其他存储代替 const hasRoom = await app.redis.get(`${PREFIX}:${room}`);
console.log(hasRoom,`${PREFIX}:${room}`) // if (!hasRoom) {
// tick(id, {
// type: 'deleted',
// message: 'deleted, room has been deleted.',
// });
// return;
// } // 用户加入
logger.debug('#join', room);
socket.join(room); // 在线列表
nsp.adapter.clients(rooms, (err, clients) => {
// 更新在线用户列表
nsp.to(room).emit('online', {
clients,
action: 'join',
target: 'participator',
message: `User(${id}) joined.`,
});
console.log(,clients)
});
// socket.emit('connect', 'packet received!'); await next();
console.log('disconnect!'); };
};

app/io/middleware/filter.js

module.exports = (app) => {
return async (ctx, next) => {
// console.log(ctx.packet);
await next();
// console.log('packet response!');
};
};
 
踢出用户示例:
 
const tick = (id, msg) => {
logger.debug('#tick', id, msg);
socket.emit(id, msg);
app.io.of('/').adapter.remoteDisconnect(id, true, err => {
logger.error(err);
});
};
Controller
Controller 对客户端发送的 event 进行处理;由于其继承于 egg.Contoller, 拥有如下成员对象:
ctx
app
service
config
logger

app/io/controller/chat.js

/**
* Created by bear on 2018/2/12.
*/
module.exports = app => {
class chatController extends app.Controller {
async index() {
this.ctx.socket.emit('res', 'test');
}
async message() { //方法通过 客户端 this.emit('message',{})//触发
this.ctx.socket.emit('message', 'test');
const params = this.ctx.args[];
// this.ctx.service.message.sendPeerMessage(params);
console.log(,params);
} async online() {// modelMessage.sendOfflineMessage(socket, data.userId);
}
}
return chatController;
};

egg-socket在egg中的使用的更多相关文章

  1. socket网络编程中read与recv区别

    socket网络编程中read与recv区别 1.read 与 recv 区别 read 原则: 数据在不超过指定的长度的时候有多少读多少,没有数据则会一直等待.所以一般情况下:我们读取数据都需要采用 ...

  2. php socket模拟http中post或get提交数据

    php socket模拟http中post或者get提交数据的示例代码. 代码: sock_post.php: <?php /** * php socket模拟post\get请求 * 编辑:脚 ...

  3. .net平台下C#socket通信(中)

    上篇.net平台下C#socket通信(上)介绍了socket通信的基本原理及最基本的通信方式.本文在此基础上就socket通信时经常遇到的问题做一个简单总结,都是项目中的一些小问题,拿来此处便于下次 ...

  4. socket服务器开发中的SO_REUSEADDR选项与让人心烦的TIME_WAIT

    1 发现问题 我在开发一个socket服务器程序并反复调试的时候,发现了一个让人无比心烦的情况:每次kill掉该服务器进程并重新启动的时候,都会出现bind错误:error:98,Address al ...

  5. RT3070 USB WIFI 在连接socket编程过程中问题总结

    最近耗时多天,成功的将RT3070驱动.并解决了socket的网络编程,成功的在BA9G10上面实现了USB wif.连上家里的无线路由器,通过ubuntu下面建立的服务端程序,将BA9G10中的数据 ...

  6. Java基础篇Socket网络编程中的应用实例

    说到java网络通讯章节的内容,刚入门的学员可能会感到比较头疼,应为Socket通信中一定会伴随有IO流的操作,当然对IO流比较熟练的哥们会觉得这是比较好玩的一章,因为一切都在他们的掌握之中,这样操作 ...

  7. [Unity Socket]在Unity中如何实现异步Socket通信技术

    在刚刚开发Unity项目的过程中,需要用到即时通信功能来完成服务器与客户端自定义的数据结构封装. 现在将部分主要功能的实现代码抽取出来实现了可以异步Socket请求的技术Demo. 客户端脚本Clie ...

  8. 关于调试php的socket服务端中遇到的问题及解决办法

    今天终于把socket的服务端解决了,期间遇到了很多问题呢~ 1.用cmd运行php的问题: 2.socket_create()函数未定义问题: 3.查看端口的问题. 以下逐一说说解决办法: 1.在c ...

  9. 【Java TCP/IP Socket】深入剖析socket——TCP通信中由于底层队列填满而造成的死锁问题(含代码)

    基础准备 首先需要明白数据传输的底层实现机制,在http://blog.csdn.net/ns_code/article/details/15813809这篇博客中有详细的介绍,在上面的博客中,我们提 ...

  10. socket listen参数中的backlog 的意义!

    服务器监听时,在每次处理一个客户端的连接时是需要一定时间的,这个时间非常的短(也许只有1ms 或者还不到),但这个时间还是存在的.而这个backlog 存在的意义就是:在这段时间里面除了第一个连接请求 ...

随机推荐

  1. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第七章:在Direct3D中绘制(二)

    原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第七章:在Direct3D中绘制(二) 代码工程地址: https:/ ...

  2. mysql的执行计划概念说明

    explain中的列的说明 1. id列 id列的编号是 select 的序列号,有几个 select 就有几个id,并且id的顺序是按 select 出现的 顺序增长的. id列越大执行优先级越高, ...

  3. [Linux]jenkins的安装 标签: linux服务器 2016-08-21 20:47 1060人阅读 评论(23)

    现阶段遇到一个问题,因为某台服务器需要腾出来,所以需要将这台服务器上jenkins的主节点重新安装到另外一台服务器上.,下面就介绍一下centos7上面jenkins的安装. 一,步骤 注意:新安装的 ...

  4. TIJ——Chapter Six:Access Control

    package:the library unit The levels of access control from "most access" to "least ac ...

  5. cume_dist(),允许并列名次、复制名次自动空缺,取并列后较大名次,结果如22355778……

    将score按ID分组排名:cume_dist() over(partition by id order by score desc)*sum(1) over(partition by id) 将sc ...

  6. Flask学习之十三 日期和时间

    英文博客地址:http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-xiii-dates-and-times 中文翻译地址: ...

  7. 8-2udp和tcp网络编程以及粘包和解决粘包的方法

    一  tcp网络编程 server 端 import socket sk=socket.socket() #实例化一个对象 sk.setsockopt(socket.SOL_SOCKET,socket ...

  8. 终端安装opencv

    安装 要想在 notebook 中安装和使用 OpenCV,请打开终端窗口(也被称为 Windows 用户的命令提示符窗口),并使用以下命令通过 conda 安装最新版本 (v3): conda in ...

  9. day2_python之字符编码

    一 .计算机基础知识 二.文本编辑器存取文件的原理(nodepad++,pycharm,word) #1.打开编辑器就打开了启动了一个进程,是在内存中的,所以,用编辑器编写的内容也都是存放与内存中的, ...

  10. oracle函数 round(x[,y])

    [功能]返回四舍五入后的值 [参数]x,y,数字型表达式,如果y不为整数则截取y整数部分,如果y>0则四舍五入为y位小数,如果y小于0则四舍五入到小数点向左第y位. [返回]数字 [示例] se ...