用node实现一个简单的聊天室——websocket实践

栏目: 后端 · 发布时间: 5年前

内容简介: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来实现客户端逻辑

用node实现一个简单的聊天室——websocket实践

简单的一个页面, 分为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

复制代码
用node实现一个简单的聊天室——websocket实践
// 客户端 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还有分房间, 踢人,身份识别,私聊等功能, 等下篇文章再写吧。

用node实现一个简单的聊天室——websocket实践

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

创业就是要细分垄断

创业就是要细分垄断

李开复、汪华、傅盛 / 文化发展出版社 / 2017-5-1 / CNY 45.00

对各方面资源极为有限的创业公司而言,想在激烈的市场竞争中站立下来的第一步是:成为细分市场的垄断者。不管是资本还是尖端人才,追逐的永远是行业里尖端的企业,第二名毫无意义。 首先,要精准定位潜在市场。这个市场的需求仍没有被满足,并且潜力巨大。其次,抓住时代和行业的红利,通过高速增长实现“小垄断”,抢滩登陆。最后,在细分领域里建立起自己的竞争壁垒,应对巨头和竞争对手的复制,去扩展更大的市场,从而扩......一起来看看 《创业就是要细分垄断》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具