前端监听websocket消息并实时弹出(实例代码)
程序员文章站
2022-01-21 20:53:40
前端监听websocket消息并实时弹出(实例代码)这篇文章主要介绍了前端监听websocket消息并实时弹出,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下... 21-11-23...
本文默认您已掌握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()) }, }, }
3、notification组件封装,结构及代码
(1)package.json
{ "name": "notification", "version": "0.0.0", "private": true, "main": "./index.js" }
(2) index.less
.notification{ .btns{ padding: 0; margin: 15px 0 0 0; list-style: none; width: 100%; display: flex; justify-content: flex-end; li{ margin-left: 10px; } } }
(3)index.js
/** * 右下角弹窗组件封装 */ import react from 'react' import { injectintl } from 'react-intl'; import moment from 'moment' import { connect } from 'dva' import { notification } from 'antd'; import demo1 from './demo1' import demo2 from './demo2' @injectintl @connect(({ websocket, }) => ({ websocket })) export default class notification extends react.component { componentwillreceiveprops(nextprops) { const {websocket,dispatch,intl, intl: { formatmessage }} = nextprops; let message=websocket.get('message'); message.foreach((note)=>{ let object=note.getin(['object']); let msgid=note.getin(['msgid']); let title=note.getin(['title']); let content=note.getin(['content']); let format = 'yyyy-mm-dd hh:mm:ss'; let time=note.getin(['ts'])?moment(note.getin(['ts']), 'x').format(format):moment().format(format); switch (object) { case 'demo1': content=<demo1 dispatch={dispatch} intl={intl} note={note} onclose={()=>this.onclose(msgid)} />; break; case 'demo2': content=<demo2 dispatch={dispatch} intl={intl} note={note} onclose={()=>this.onclose(msgid)} />; break; default: break; } notification.open({ message: <span>{title} <small>{time}</small></span>, duration:30, key: msgid, description:content, placement: 'bottomright', onclick: () => { }, onclose: () => { this.onclose(msgid); } }); }) } // 关闭消息 onclose=(msgid)=>{ const {dispatch} = this.props; dispatch({ type:'websocket/removeonemessage', payload:{ msgid } }) return notification.close(msgid); } render(){ return( null ) } } notification.proptypes = { }
(4)demo1.js
import react from 'react' import styles from './index.less' export default class notificationson extends react.component { render(){ const {note,intl:{formatmessage}} = this.props; let content=note.getin(['content']); return( <div classname={styles.notification}> <div>{content}</div> </div> ) } } notificationson.proptypes = { }
(5)demo2.js
import react from 'react' import styles from './index.less' import { config } from 'utils' import { button } from 'antd'; const { defaultstylesize } = config; export default class notificationson extends react.component { dealapproval=(type,data)=>{ const {dispatch,onclose} = this.props; if(type=='refuse'){ console.log('拒绝') onclose(); }else if(type=='agree'){ console.log('同意') onclose(); } } render(){ const {note,intl:{formatmessage}} = this.props; let content=note.getin(['content']); return( <div classname={styles.notification}> <div>{content}</div> <ul classname={styles.btns}> <li> <button style={{ marginleft: '12px' }} type={'primary'} size={defaultstylesize} onclick={() => {this.dealapproval('agree',note.get('data'))}}>{formatmessage({id: 'global.agree'})}</button> </li> <li> <button style={{ marginleft: '12px' }} type={'danger'} size={defaultstylesize} onclick={() => {this.dealapproval('refuse',note.get('data'))}}>{formatmessage({id: 'global.refuse'})}</button> </li> </ul> </div> ) } } notificationson.proptypes = { }
express模拟消息:
到此这篇关于前端监听websocket消息并实时弹出的文章就介绍到这了,更多相关websocket消息监听内容请搜索以前的文章或继续浏览下面的相关文章,希望大家以后多多支持!