1 Star 0 Fork 0

Sam / wx_webSocket

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

node + WebSocket 微信小程序聊天室

github:https://github.com/fancaixia/wx_webSocket

https://github.com/fancaixia/wx_websoket/blob/master/pic/chat.png

案例思路:

[1] 用户进入聊天室

  • 前台向后台发送连接请求并携带用户id
  • 后台 let clients:[]
  • clients.push(ws:'socket对象',id:'用户id')
  • 向前台广播当前聊天室人数

[2] 用户退出聊天室

  • 后台遍历clients 查找与当前用户id 对应数据在cliens中删除
  • 向前台广播当前聊天室人数

[3] 聊天室用户发普通消息时

  • 后台收到消息并且向每个ws对象广播消息

[4] 聊天室用户发图片时

  • 先将图片上传至服务器 (server / upload 目录)
  • 然后广播 图片地址
  • 前台接收图片路径并渲染页面

前台接收消息类型 type: message(普通消息) / image(图片消息) / loginin(进入聊天室) / loginout(退出聊天室)

~~~未解决: 微信小程序中onSocketOpen 在真机上不触发回调~~~
~~~后端数据存储没做研究~~

代码结构:

服务端代码

server

node_modules        项目依赖文件
router        处理上传文件模块
upload        图片上传目录
utils        工具函数
app.js        node主文件

小程序端代码

static

utils        配置http及ws 地址
pages

home        首页,处理websocket 连接
chat        聊天室页面

项目启动:

cd / server
cnpm install
npm run dev

小程序端模拟多人聊天

copy static
static / app.js 修改 UserId 然后进入聊天室(前台根据 UserId 判断发送消息人 )

小程序代码片段:

pages / home / index.js

// pages/home/index.js
let config = require('../../utils/config.js')
let app = getApp();

Page({

  data: { },
  onLoad: function (options) {

  },

  // 创建 websocket  连接
  webSocket(user_id) {

    //loading 动画
    wx.showNavigationBarLoading()

    // 创建Socket 对象
    app.globalData.SocketTask = wx.connectSocket({
      url: `${config.wsAddress}?id=${user_id}`,
      data: '',
      header: {
        'content-type': 'application/json'
      },
      method: 'post',
      success: function (res) {
        console.log('WebSocket连接创建', res)
      },
      fail: function (err) {
        wx.showToast({
          title: '网络异常!',
        })
        console.log(err)
      },
    })

    app.globalData.SocketTask.onOpen(res => {

        console.log('WebSocket 连接打开', res)
        wx.hideNavigationBarLoading()
        wx.navigateTo({
          url: '/pages/chat/index'
        })

    })

    app.globalData.SocketTask.onError(res => {

      console.log('WebSocket 连接失败', res)

    })

    app.globalData.SocketTask.onMessage(msg => {

      app.globalData.Chatusers = JSON.parse(msg.data).len;

    })

  },
  gotochat(){

    // 后台发请求 建立连接 
    // 携带user_id  (此user_id 应为登陆后的user_id)
    this.webSocket(app.globalData.UserId);

  }

})

pages / chat / index.js

let config = require('../../utils/config.js')
let app = getApp();
Page({

  data: {
     socketMsg : '',  // 发送消息
     msg_data:[],      //会话内容 
  },

  // 进入页面获取 app.globalData.SocketTask
  onLoad(){

    wx.setNavigationBarTitle({
      title: '聊天室人数 / ' + app.globalData.Chatusers
    })

  },
  // 退出页面 断开socket 连接
 onUnload(){

   this.close_websocket();
   

 },
  onReady () {

    let { SocketTask } = app.globalData;
   
    SocketTask.onClose(onClose => {
      // console.log('监听 WebSocket 连接关闭事件。', onClose)

      this.close_websocket();

    })
    SocketTask.onError(onError => {
      // console.log('监听 WebSocket 错误。错误信息', onError)

      this.close_websocket();

    })
    SocketTask.onMessage(msg => {
      console.log('服务端数据返回:',msg)

      let { msg_data } = this.data;
      let { type } = JSON.parse(msg.data);

      // type 类型,message:普通消息,image:图片 , loginout:退出,  loginin:进入
      if (type == "message"){

        let { nickname, message, fromId } = JSON.parse(msg.data);
        // 根据app.globalData.UserId(当前用户id)判断发消息人
        let fromuser = 'other'
        if (fromId == app.globalData.UserId){
          fromuser = 'me'
        }

        msg_data.push({ type, nickname, message, fromId, fromuser })
        this.setData({
          msg_data,
        })

      } else if (type == "loginout" || type == "loginin"){

        // 用户退出 / 进入 聊天室
        app.globalData.Chatusers = JSON.parse(msg.data).len;
        wx.setNavigationBarTitle({
          title: '聊天室人数 / ' + app.globalData.Chatusers
        })

      } else if (type == "image" ){

        // 图片上传服务器成功后  ws广播
        let { msg_data } = this.data;
        let { src, type, fromId } = JSON.parse(msg.data);

        let fromuser = 'other'
        if (fromId == app.globalData.UserId) {
          fromuser = 'me'
        }
        msg_data.push({ type, src: `${config.httpAddress}/${src}`, fromId, fromuser, })

        this.setData({
          msg_data,
        })

      }

    })
  },

  // 断开连接
  close_websocket(){
    
    let { SocketTask } = app.globalData;

    if (app.globalData.SocketTask){
      SocketTask.close({
        code: 1000,
        success: (res) => {
          console.log('关闭成功', res)

          app.globalData.SocketTask = null;

        },
        fail: function (err) {
          console.log(err, "网络异常")
        },
        complete: () => {
          console.log('完成')
        }

      })
    }
    

  },

  // 更改 inpiut  value
  setstr(e){
      this.setData({
        socketMsg : e.detail.value
      })
  },
// 发送消息  
  sendMsg(){
    let { socketMsg } = this.data; 
    let { SocketTask } = app.globalData;

    // 检测空字符
    socketMsg = socketMsg.trim();
    if (socketMsg.length == 0){
      return;
    }

    SocketTask.send({
      data: socketMsg,
      success: (res) => {
        // console.log('发送成功', res)
        this.setData({
          socketMsg:''
        })
      },
      fail: function (err) {
        console.log(err,"网络异常")
      },

    })


  },
  // 图片上传
  add_photo(){
    let $this = this;

    wx.chooseImage({
      success(res) {

        const tempFilePaths = res.tempFilePaths

        const uploadTask = wx.uploadFile({
          url: `${config.httpAddress }/upfile/add`, // 图片上传接口地址
          filePath: tempFilePaths[0],
          name: 'file',
          formData: {
            'fromId': app.globalData.UserId
          },
          success(res) {
            // console.log(res,"图片上传到服务器")
          }
        })

      }
    })
  }


});

node / app.js

let koa = require('koa')
const staticFile = require('koa-static')
let router = require('./router/upfile')
let path = require('path')
let url = require('url')

let ws = require('ws')
let socketServer = ws.Server
let utils = require('./utils/utils')


let app = new koa();
app.use(staticFile(path.join(__dirname + '/upload/'))) // 配置默认访问地址

let wss = new socketServer({port: 8080});    //创建websocketServer实例监听8080端口
let clientObj = require('./utils/setClients');  //创建客户端列表,用于保存客户端及相关连接信息

//监听连接
wss.on('connection', function(ws,req) {

    var parseObj = url.parse(req.url, true);

    clientObj.add({
        "id": parseObj.query.id,
        "ws": ws,
    })

    // 向前台发送聊天室用户信息
    utils.openSocket(ws, parseObj.query.id)

    /*监听并广播消息*/
    ws.on('message', function(message) {

        utils.broadcastSend(ws, "message", message, parseObj.query.id);
       
    });
    /*监听断开连接*/
    ws.on('close', function() {
        utils.closeSocket(ws, parseObj.query.id);
    })
})


app.use(router.routes());

app.listen(8090)

空文件

简介

暂无描述 展开 收起
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
1
https://gitee.com/windgap/wx_webSocket.git
git@gitee.com:windgap/wx_webSocket.git
windgap
wx_webSocket
wx_webSocket
master

搜索帮助