Github StackChat

  1. const app = require('express')()
  2. const http = require('http').createServer(app)
  3. const io = require('socket.io')(http)
  1. const url = `http://localhost:8008`
  2. const socket = io(url)
  1. //客户端
  2. const url = `http://localhost:8008?user=${query}`
  3. const socket = io(url)
  4. //服务器端
  5. const query = socket.handshake.query
  6. //query.user === ${query}

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

  • eventName
  • args
  • ack
  • return Socket

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

socket.on(eventName,callback)

  • eventName
  • callback
  • return Socket

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

  1. const socket = getState().connect.socket
  2. const email = getState().login.email //1001@qq.com
  3. socket.emit('will_close', email)
  4. socket.on('will_close', (closeUser) => {
  5. //closeUser 1001@qq.com
  6. deleteSocket(closeUser)
  7. })

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

添加好友的流程大概如下

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

  • 搜索框进行添加请求

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

  1. //搜索好友框的container
  2. const mapDispatchToProps = dispatch => ({
  3. onChangeSearchInput: (event) => {
  4. dispatch(searchInputChange(event.target.value))
  5. },
  6. handleAddFriend: () => {
  7. dispatch(addFriend())
  8. },
  9. })

handleAddFriend才是处理好友添加请求

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

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

  1. function sendFriendRequest({ origin, dest }, socket) {
  2. mongonConnect
  3. .then(db => findFriend(db, dest))
  4. .then(() => {
  5. const destUser = findSocketFromEmail(dest)
  6. const mr = {
  7. origin,
  8. message: `Friend add request from ${origin}`,
  9. }
  10. destUser.socket.emit('add_friend_request', mr)
  11. })
  12. .catch((message) => {
  13. if (message === USER_NO_EXIST) {
  14. socket.emit('add_friend_response', USER_NO_EXIST_MESSAGE)
  15. } else if (message === ADD_FRIEND_FAILED) {
  16. socket.emit('add_friend_response', ADD_FRIEND_FAILED_MESSAGE)
  17. }
  18. })
  19. }
  • 另一个客户端进行响应,并发送到服务器

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

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

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

  1. socket.on('add_friend_response', (data) => {
  2. const desk = findSocketFromEmail(data.info.dest)
  3. if (data.pick) {
  4. addFriend(data.info.origin, data.info.dest, desk.socket)
  5. } else {
  6. desk.socket.emit('add_friend_response', ADD_FRIEND_BE_REJECTET)
  7. }
  8. })

添加好友的数据库操作

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

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

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

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

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

版权声明:本文为secoding原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/secoding/p/11150908.html