内容简介:websocket是HTML5开始提供的一种在单个TCP连接上进行全双工通讯的协议。大多数 Web 应用程序将通过频繁的异步JavaScript和XML(AJAX)请求实现长轮询。轮询的效率低,非常浪费资源。而websocket能够很好的解决类似的问题。常用于即时通讯、监控等情况。 在本案例中, 使用egg+typescript作为后端框架, 使用egg官方封装的Socket.IO库。前端使用vue。TS下的egg许多设置和文档有所不同, 但是稍稍看一下还是能理解的。 按照egg的文件规划,Socket.
websocket是HTML5开始提供的一种在单个TCP连接上进行全双工通讯的协议。大多数 Web 应用程序将通过频繁的异步JavaScript和XML(AJAX)请求实现长轮询。轮询的效率低,非常浪费资源。而websocket能够很好的解决类似的问题。常用于即时通讯、监控等情况。 在本案例中, 使用egg+typescript作为后端框架, 使用egg官方封装的Socket.IO库。前端使用vue。
egg配置
TS下的egg许多设置和文档有所不同, 但是稍稍看一下还是能理解的。 按照egg的文件规划,Socket.IO应该独立的作为一个文件夹, 内部包含自己的controller和middleware, 然后和其他页面共享router配置
// router export default (app: Application) => { const { controller, router, io } = app; // Socket.IO会通过io暴露出来, io.of('/')则是命名空间 router.get('/', controller.home.index); // 这个是正常的http请求 io.of('/').route('online', io.controller.nsp.exchange); // 这个就是websocket请求 io.of('/').route('newmsg', io.controller.nsp.newmsg); io.of('/').route('sendMsg', io.controller.nsp.sendMsg); }; 复制代码
// config/plugin 这里是egg开启插件插件的地方 const plugin: EggPlugin = { // static: true, nunjucks: { enable: true, package: 'egg-view-nunjucks', // 模板渲染插件 }, io: { enable: true, package: 'egg-socket.io', // 官方的封装的socke插件 }, }; 复制代码
// config/config.default 根据不同环境, 配置插件参数 export default (appInfo: EggAppInfo) => { // ... config.middleware = []; // 配置模板引擎 config.view = { cache: false, defaultExtension: 'nunjucks', mapping: { '.html': 'nunjucks', }, }; // 配置socket config.io = { init: { }, // passed to engine.io namespace: { // 命名空间 '/': { connectionMiddleware: [ 'connection', // 这个是连接中间件, 只在connection的时候触发 ], packetMiddleware: [], // 这个会在每次消息的时候触发 }, '/example': { connectionMiddleware: [], packetMiddleware: [], }, }, }; return config; }; 复制代码
// app/router export default (app: Application) => { const { controller, router, io } = app; router.get('/', controller.home.index); // 这里的sendMsg相当于一个接口, 负责处理客户端发送的sendMsg事件 // 这个controller是io模块的controller, 和egg的controller不同 io.of('/').route('sendMsg', io.controller.nsp.sendMsg); }; 复制代码
// app/io/controller import { Controller } from 'egg'; export default class NspController extends Controller { public async sendMsg() { const { ctx, app } = this; const nsp = app.io.of('/'); const message = ctx.args[0] || {} // 向客户端广播消息, 在客户端监听broadcast事件就可以获取消息了 nsp.emit('broadcast', message) } } 复制代码
// app/io/middleware/connection import { Context } from 'egg'; // io模块的中间件, 在config/config.default里配置成connectionMiddleware, 只在 connection的时候触发 export default function robotMiddleware() { return async (ctx: Context, next: any) => { const { app } = ctx; const nsp = app.io.of('/'); // 向客户端推送online事件 nsp.emit('online', '有新成员加入聊天室了') await next(); }; } 复制代码
这样, 服务器端的逻辑就完成了,接下来通过vue来实现客户端逻辑
简单的一个页面, 分为MsgItem和Send 两个组件, 具体实现就不写了。
// 客户端 src/utils/io import io from 'socket.io-client'; // 稍微封装一下socket.io, 然后暴露出去。 const socket = function ():any { const _io = io('http://127.0.0.1:7001/'); _io.on('connect', function(){ console.log('链接成功'); }); _io.on('disconnect', function(){ console.log('断开连级'); }); return _io } export default socket 复制代码
// 客户端 app/App.vue export default class Index extends Vue { // 头像 user = { avatar: 'https://f12.baidu.com/it/u=4263977612,1595937908&fm=76' } // 消息列表 msgList: Array<string> = [] //发送消息, 触发sendMsg事件 sendMsg(msg: string):void { socket.emit('sendMsg', msg) } // 页面加载之后触发 mounted() { // 监听online事件 socket.on('online', (data: string) => { this.msgList.push(data) }) // 监听broadcast事件, 获取服务器消息 socket.on('broadcast', (data: string) => { this.msgList.push(data) }) } } 复制代码
socket是基于事件监听来进行的, 通过on来注册监听事件, 通过emit来触发事件。 通过服务器和客户端的配合, 就可以事件即时的消息推送。这篇文章只写了最简单功能, 基于socket.io还有分房间, 踢人,身份识别,私聊等功能, 等下篇文章再写吧。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。