欢迎访问艾立兹站 Aliz- 专注建站教程与技术分享
您当前的位置:首页 > 建站教程 > WordPress 建站

前端监听websocket消息并实时弹出(实例代码)

时间:2023-12-30 08:33:32  来源:[db:出处]  作者:[db:作者]  阅读:

本文默认您已掌握react生态开发的相关技术,并熟练应用umiJS的原则上,请继续!

项目需求:

1、服务侧推送给消息给前端,前端需要展示在右下角
2、根据不同的消息类型,提供不同的操作按钮‘同意’、‘拒绝’等

代码设计:

1、使用websocket方式建立通道
2、前端基于umi+antd+reconnecting-websocket.js开发
3、使用express+express-ws+mockjs建立websocket服务通道,模拟服务端推送消息

运行效果:

使用方法:

1、项目中已引入reconnecting-websocket.min.js,详见其官方文档

2、登录成功后,接着调用websocket初始化:

yield put({
    type: 'websocket/init',
    payload: {
        authToken
    }
});

核心代码:

1、/service/websocket.js

/**
 * 基于reconnecting-websocket库已引入
 * 封装service文件
 */
class Websocket{
 
  /**
   * websocket逻辑
   * 2021-10-28
   */
 
  constructor(){
    this.websocket=null;
    this.url='ws://127.0.0.1:30001/websocket-im';
    this.options={
      connectionTimeout: 5000,
      maxRetries: 10,
    };
  }
 
  init=()=>{
    this.websocket = new ReconnectingWebSocket(this.url,[], this.options);
  }
 
  close=()=>{
    this.websocket && this.websocket.close();
  }
 
  onMessage=(callback)=>{
    this.websocket && this.websocket.addEventListener('message', (e) => {
      callback&&callback(e)
    });
  }
 
}
 
const websocket = new Websocket();
 
// 初始化连接
export function openWs() {
  return websocket.init();
}
 
// 关闭连接
export function closeWs() {
  return websocket.close();
}
 
// 监听websocket消息
export function onMessage() {
  let deferred;
  websocket.onMessage(function(e){
    if(deferred) {
        deferred.resolve(e)
        deferred = null 
    }
  });
  return {
    message() {
      if(!deferred) {
          deferred = {}
          deferred.promise = new Promise(resolve => deferred.resolve = resolve)
      }
      return deferred.promise;
    }
  }
}
 

2、/model/websocket.js

 
/**
 * 封装model文件
 * moment、immutable、antd、nanoid组件请自行学习
 */
import {openWs,onMessage,closeWs} from 'services/websocket'
import moment from 'moment'
import { Map, fromJS } from 'immutable'
import { notification } from 'antd'
import nanoid from 'nanoid';
 
const initState = Map({
 
  message:Map(), //收到的消息
  
});
export default {
  namespace: 'websocket',
 
  state: initState,
  subscriptions: {
    setup({ dispatch, history }) {
      dispatch({
        type: 'listener'
      });
      return history.listen(({ pathname, query }) => {
        
      });
    },
  },
  effects: {
 
    * listener({ payload }, { take, put, call }) {
      while (true) {
        const { type, payload } = yield take(['logout']);
        
        // 监听退出系统,则关闭websocket
        if (type === 'logout') {
          // 关闭websocket
          yield call(closeWs);
          notification.destroy();
          yield put({
            type: 'clearAllMessage', 
            payload:{
            }
          });
        }
      }
    },
 
    // 启动websocket
    * init ({
      payload,
    }, { put, call, select }) {
      yield call(openWs);
      const listener = yield call(onMessage);
      yield put({type: 'receiveMsg', payload:{listener}});
    }, 
 
    // 接受消息
    * receiveMsg ({
        payload: {listener}
    }, { call, select, put}) {
        while(true){
          const event = yield call(listener.message);
 
          yield put({
            type: 'progressMsg', 
            payload:{
              msg:JSON.parse(event.data)
            }
          });
          
            
        }
    },
 
    // 统筹消息
    * progressMsg ({
        payload: {msg}
    }, { call, select, put}) {
 
      console.log(msg)
      
      yield put({
        type: 'addOneMessage', 
        payload:{
          msg
        }
      });
        
    },
 
  },
  
  reducers: {
    
    addOneMessage(state, { payload:{msg} }) {
   
      const msgId = nanoid()+'-'+moment().format('x');
      return state.setIn(['message',msgId], fromJS({...msg,msgId}))
 
    },
 
    removeOneMessage(state, { payload:{msgId} }) {
   
      return state.deleteIn(['message',msgId])
 
    },
 
    clearAllMessage(state, { payload:{} }) {
   
      return state.setIn(['message'],Map())
 
    },
    
 
  },
  
}                    
                    
                    

本文配套模板、静态源码可前往艾立兹素材库alisucai.com下载

发表评论 共有0条评论
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表
公众号二维码

扫码关注公众号
获取全套技术教程