nodejs:实现webim(websocket方式) websocket聊天应用

webim(Instant Messaging,im即时通讯)
websocket是双向服务
nodejs有两个常用的库: ws(原生websocket协议实现的) Socket.io(对websocket进行的封装,并且兼容不支持的socktio的浏览器)

websocket可以主动向客户端发送消息: 如外卖众包平台的最新订单,安卓的消息推送好像也是

在这里插入图片描述
在这里插入图片描述

一:ws

npm i ws
// 客户端

const WebSocket = require('ws')


const wss = new WebSocket('ws://127.0.0.1:8000')

wss.on('open', function () { // 接受open事件
    wss.send('hellow', 0) // 1.发给服务端
    wss.on('message',function(msg){
        console.log(msg) // 2.接受服务端
    })
})

// 服务端

const WebSocket = require('ws')


const wss = new WebSocket.Server({ port: 8000 })

wss.on('connection', function (ws) {
    ws.on('message', function (msg) { // 监听message事件
        console.log(msg) // 1.接受客户端
    })
    ws.send('message from server') // 2.接受客户端
})

二:socket.io

三: websocket聊天应用

//client/index.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <div id="app">
    <!-- 用户输入昵称后才能进入聊天室 -->
    <div v-if="flag">
      <input type="text" value="请输入昵称" v-model="name">
      <button @click="into">进入聊天室</button>
    </div>
    <div v-else>
      <div>在线人数:{{num}}</div>
      <div class="list" v-for="(item,index) in list" :key="index">{{item.message}}</div>
      <input type="text" v-model="ipt">
      <button @click="sumbit">发送</button>
    </div>

  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue"></script>
  <script>
    // 1.发送消息
    // 客户端 取input值 -> websocket -> 发送到服务器 -> 转发给其它的所有客户端
    var app = new Vue({
      el: '#app',
      data: function () {
        return {
          list: [{ message: 'message' }],
          ipt: 'hello',
          wsHandle: '',
          flag: true,
          name: '',
          num: 0
        }
      },
      methods: {

        onOpen: function () {
          console.log('client is connected')
        },
        // 收到消息
        onMessage: function (evt) {
          // 把数据推送到list中
          var msg = JSON.parse(evt.data)
          if (msg.num) { this.num = msg.num }
          if (msg.event === 'login') {
            this.list.push({
              message: '欢迎' + msg.name + '加入聊天室'
            })
          } else if (msg.event === 'logout') {
            this.list.push({
              message: msg.name + '退出了聊天室'
            })
          }
          else {
            if (msg.name !== this.name) { // 不等于当前用户去推送
              this.list.push({
                message: msg.name + ':' + msg.message
              })
            }
          }

        },
        // 输入昵称后的聊天书界面
        sumbit: function () {
          // 取inputvalue
          // 通过webSocket发送数据
          console.log(this.ipt)
          this.wsHandle.send(JSON.stringify({
            message: this.ipt,
            name: this.name,
            event: 'message'
          }))
          this.list.push({
            message: this.name + ':' + this.ipt
          })
          this.ipt = ''
        },
        // 输入昵称登录
        into: function () {
          if (this.name.trim() === '') {
            return alert('用户昵称不能为空')
          }
          console.log(this.name)
          this.wsHandle.send(JSON.stringify({
            name: this.name,
            event: 'login'
          }))
          this.flag = false
        }
      },
      mounted() {
        var _this = this
        this.wsHandle = new WebSocket('ws://localhost:8000')
        this.wsHandle.onopen = this.onopen
        // 服务端发送回来的其它消息
        this.wsHandle.onmessage = this.onMessage
      }
    })
  </script>
</body>

</html>

服务端

// /server/index.js
const WebSocket = require('ws')


const wss = new WebSocket.Server({ port: 8000 })

wss.on('connection', function (ws) {
  console.log('a new client is connected')
  ws.on('message', function (msg) { // 监听message事件
    // 将受到的msg广播到其它客户端
    let msgObj = JSON.parse(msg)
    msgObj.num = wss.clients.size // 连接数量

    if (msgObj.name) {
      ws.name = msgObj.name
    }

    wss.clients.forEach(function each (client) { // 广播代码
      // 广播给非自己的客户端 client !== ws &&
      // 这里是广播所有用户,包括自己
      if (client.readyState === WebSocket.OPEN) {
        //  WebSocket.OPEN readyState属性返回实例对象的当前状态,共有四种 OPEN:值为1,表示连接成功
        client.send(JSON.stringify(msgObj))
      }
    })
  })
  ws.on('close', function () {
    if (typeof ws.name !== 'undefined') { // ws.name存在才广播
      console.log('onee client is closed:' + ws)
      wss.clients.forEach(function each (client) { // 广播代码
        // 广播给非自己的客户端 client !== ws &&
        // 这里是广播所有用户,包括自己
        if (client.readyState === WebSocket.OPEN) {
          //  WebSocket.OPEN readyState属性返回实例对象的当前状态,共有四种 OPEN:值为1,表示连接成功
          client.send(JSON.stringify({
            name: ws.name,
            event: 'logout',
            num: wss.clients.size
          }))
        }
      })
    }
  })
  //     ws.send('message from server') // 2.接受客户端
})



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WebIM说明 WebIM是一款基于jQuery的一款web即时通讯插件,姑且这么称呼吧。插件最大程度实现IM的常用功能,除即时通讯的常用功能外,还加入了:消息盒子、窗口抖动、添加删除好友、最近联系人、超时登录界面、网站小秘书、聊天记录、发送频率限制、发送产品、发送名片、发送表情、产品分享、黑名单、举报、收藏、公告、智能网址过滤、消息提醒、修改资料、名片二维码、禁止粘贴、收起联系人列表、推荐好友等30余项改进。全浏览器兼容。 插件调用简单方便,只需在现有的web系统中加入几行代码,理论上可嵌入任何web系统。 2012年项目,已不再维护。 配置 $(function() { $(document).FnWebIM({ autoLogin :true, //boolean型,默认是否自动登录,true:自动登录,false:手动登录,默认为true msgRefreshTime :1000, //number型,消息刷新时间,单位为ms friendRefreshTime :10000, //number型,好友刷新时间,单位为ms showSecretary :true, //boolean型,默认是否显示小秘书,true:显示,false:不显示,默认为true noticeContent :"唐僧师徒历经千辛万苦,终于见到了佛祖……", //string型,公告内容 为空时不显示公告 sendPicture :true, //boolean型,是否允许发送图片,true:允许,false:不允许,默认为true msgMaxSize :300, //number型,单条消息最大允许字符 msgSound :false, //boolean型,是否开启声音提醒,true:开启,false:关闭,默认为true defaultWindow :"" //string型,登录后打开新聊天窗口,此处接收的参数为联系人的uid,否则会出错 }); }); 详细说明文档 http://www.zi-han.net/case/im/help.html 示例 http://www.zi-han.net/developer/721.html 注意 请在服务器(如localhost)环境下打开

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值