• Node.js实现PC端类微信聊天软件(五)


    Github StackChat

    学习回顾

    Socket.io

    结合Express创建Socket.io服务器

    const app = require('express')()
    const http = require('http').createServer(app)
    const io = require('socket.io')(http)
    

    客户端进行连接

    const url = `http://localhost:8008`
    const socket = io(url)
    

    url传参

    //客户端
    const url = `http://localhost:8008?user=${query}`
    const socket = io(url)
    //服务器端
    const query = socket.handshake.query
    //query.user === ${query}
    

    进行通信

    socket.emit

    socket.emit(eventName [,... args] [,ack])

    • eventName
    • args
    • ack
    • return Socket

    将事件发送到由字符串名称标识的套接字。可以包括任何其他参数。支持所有可序列化的数据结构,包括Buffer。

    socket.on

    socket.on(eventName,callback)

    • eventName
    • callback
    • return Socket

    为给定事件注册新的处理程序。

    example

    const socket = getState().connect.socket
    const email = getState().login.email //1001@qq.com
    socket.emit('will_close', email)
    
    socket.on('will_close', (closeUser) => {
      //closeUser 1001@qq.com
      deleteSocket(closeUser)
    })
    

    完成的部分

    完结篇,接下来的所有功能基本都可以用现在的套路来实现,都是基于socket.io来进行服务器端和客户端的通信

    好友添加

    添加好友的流程大概如下

    1. 搜索框进行添加请求
    2. 把信息发送到服务器
    3. 服务器转发到另一个客户端
    4. 通知栏显示通知
    5. 另一个客户端进行同意或拒绝响应发送到服务器
    6. 服务器转发到之前请求的客户端并在通知栏显示

    • 搜索框进行添加请求

    onChangeSearchInput主要是改变搜索框输入的state

    //搜索好友框的container
    const mapDispatchToProps = dispatch => ({
      onChangeSearchInput: (event) => {
        dispatch(searchInputChange(event.target.value))
      },
      handleAddFriend: () => {
        dispatch(addFriend())
      },
    })
    

    handleAddFriend才是处理好友添加请求

    //添加好友的action
    export const addFriend = () => (dispatch, getState) => {
      const socket = getState().connect.socket
    
      socket.emit('add_friend', {
        origin: getState().login.email,
        dest: getState().search.input,
      })
    }
    
    • 服务器进行转发

    服务器把添加好友的请求转发给另一个客户端

    function sendFriendRequest({ origin, dest }, socket) {
      mongonConnect
        .then(db => findFriend(db, dest))
        .then(() => {
          const destUser = findSocketFromEmail(dest)
          const mr = {
            origin,
            message: `Friend add request from ${origin}`,
          }
          destUser.socket.emit('add_friend_request', mr)
        })
        .catch((message) => {
          if (message === USER_NO_EXIST) {
            socket.emit('add_friend_response', USER_NO_EXIST_MESSAGE)
          } else if (message === ADD_FRIEND_FAILED) {
            socket.emit('add_friend_response', ADD_FRIEND_FAILED_MESSAGE)
          }
        })
    }
    
    • 另一个客户端进行响应,并发送到服务器

    pick为客户端对好友请求做出的响应,true or false

    export const responseMessage = pick => (dispatch, getState) => {
      const response = {
        pick,
        info: {
          origin: getState().login.email,
          dest: getState().notification.originEmail,
        },
      }
      const socket = getState().connect.socket
      socket.emit('add_friend_response', response)
    }
    
    • 服务器接收到响应,进行数据库操作,并进行对进行请求的客户端回应

    如果pick为真就代表同意添加好友

    socket.on('add_friend_response', (data) => {
      const desk = findSocketFromEmail(data.info.dest)
      if (data.pick) {
        addFriend(data.info.origin, data.info.dest, desk.socket)
      } else {
        desk.socket.emit('add_friend_response', ADD_FRIEND_BE_REJECTET)
      }
    })
    

    添加好友的数据库操作

    function addFriendService(origin, dest, socket) {
      mongonConnect
        .then(db => addFriend(db, { origin, dest }))
        .then((message) => {
          if (message === ADD_FRIEND_SUCCESS) {
            socket.emit('add_friend_response', ADD_FRIEND_SUCCESS_MESSAGE)
          }
        })
        .catch((message) => {
          if (message === USER_NO_EXIST) {
            socket.emit('add_friend_response', USER_NO_EXIST_MESSAGE)
          } else if (message === ADD_FRIEND_FAILED) {
            socket.emit('add_friend_response', ADD_FRIEND_FAILED_MESSAGE)
          }
        })
    }
    
    • 之前进行请求的客户端接收服务器端的响应,添加成功或者失败
    socket.on('add_friend_response', (data) => {
      const res = JSON.parse(data)
      dispatch(newMessage(res))
    })
    

    总结

    之后所有的操作包括聊天功能,朋友圈功能,基本都是按照这个套路基于socket.io进行通信来实现

    1. 进行action的描述,作为通过view层进行触发来和服务器通信(需要利用redux中间件),接收到服务器的消息后再进行dispatch更改view

    2. reducer,通过dispatch来进行作用,通过action和当前state来改变state从而对view进行更新

    3. 先对需要的展示组件进行改造,改造成容器组件,可以对state进行操作,利用mapStateToProps,mapDispatchToProps,把state和dispatch映射到组件上,通过state的内容来动态展示和服务器交互的内容,使得可以通过view才来触发状态的改变

  • 相关阅读:
    在Ubuntu1804上使用Apache2的部署Django配置
    UbuntuServer1804设置uwsgi自启动服务
    ubuntu 安装k8s 1.22.3 (VirtualBox虚拟机)
    启动keepalived 报错
    wasm-pack 编译错误 unexpected character 'u{0}'
    mariadb-安装
    K8S1.18 安装教程
    Ubuntu共享文件权限问题
    docker 安装consul
    Ubuntu 安装 MySQL 和远程连接
  • 原文地址:https://www.cnblogs.com/secoding/p/11150908.html
Copyright © 2020-2023  润新知