• 设为首页
  • 收藏本站
  • 积分充值
  • VIP赞助
  • 手机版
  • 微博
  • 微信
    微信公众号 添加方式:
    1:搜索微信号(888888
    2:扫描左侧二维码
  • 快捷导航
    福建二哥 门户 查看主题

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

    发布者: Error | 发布时间: 2025-6-16 12:18| 查看数: 86| 评论数: 0|帖子模式

    本文默认您已掌握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初始化:
    1. yield put({
    2.     type: 'websocket/init',
    3.     payload: {
    4.         authToken
    5.     }
    6. });
    复制代码
    核心代码:

    1、/service/websocket.js
    1. /**
    2. * 基于reconnecting-websocket库已引入
    3. * 封装service文件
    4. */
    5. class Websocket{

    6.   /**
    7.    * websocket逻辑
    8.    * 2021-10-28
    9.    */

    10.   constructor(){
    11.     this.websocket=null;
    12.     this.url='ws://127.0.0.1:30001/websocket-im';
    13.     this.options={
    14.       connectionTimeout: 5000,
    15.       maxRetries: 10,
    16.     };
    17.   }

    18.   init=()=>{
    19.     this.websocket = new ReconnectingWebSocket(this.url,[], this.options);
    20.   }

    21.   close=()=>{
    22.     this.websocket && this.websocket.close();
    23.   }

    24.   onMessage=(callback)=>{
    25.     this.websocket && this.websocket.addEventListener('message', (e) => {
    26.       callback&&callback(e)
    27.     });
    28.   }

    29. }

    30. const websocket = new Websocket();

    31. // 初始化连接
    32. export function openWs() {
    33.   return websocket.init();
    34. }

    35. // 关闭连接
    36. export function closeWs() {
    37.   return websocket.close();
    38. }

    39. // 监听websocket消息
    40. export function onMessage() {
    41.   let deferred;
    42.   websocket.onMessage(function(e){
    43.     if(deferred) {
    44.         deferred.resolve(e)
    45.         deferred = null
    46.     }
    47.   });
    48.   return {
    49.     message() {
    50.       if(!deferred) {
    51.           deferred = {}
    52.           deferred.promise = new Promise(resolve => deferred.resolve = resolve)
    53.       }
    54.       return deferred.promise;
    55.     }
    56.   }
    57. }
    复制代码
    2、/model/websocket.js

    1. /**
    2. * 封装model文件
    3. * moment、immutable、antd、nanoid组件请自行学习
    4. */
    5. import {openWs,onMessage,closeWs} from 'services/websocket'
    6. import moment from 'moment'
    7. import { Map, fromJS } from 'immutable'
    8. import { notification } from 'antd'
    9. import nanoid from 'nanoid';

    10. const initState = Map({

    11.   message:Map(), //收到的消息
    12.   
    13. });
    14. export default {
    15.   namespace: 'websocket',

    16.   state: initState,
    17.   subscriptions: {
    18.     setup({ dispatch, history }) {
    19.       dispatch({
    20.         type: 'listener'
    21.       });
    22.       return history.listen(({ pathname, query }) => {
    23.         
    24.       });
    25.     },
    26.   },
    27.   effects: {

    28.     * listener({ payload }, { take, put, call }) {
    29.       while (true) {
    30.         const { type, payload } = yield take(['logout']);
    31.         
    32.         // 监听退出系统,则关闭websocket
    33.         if (type === 'logout') {
    34.           // 关闭websocket
    35.           yield call(closeWs);
    36.           notification.destroy();
    37.           yield put({
    38.             type: 'clearAllMessage',
    39.             payload:{
    40.             }
    41.           });
    42.         }
    43.       }
    44.     },

    45.     // 启动websocket
    46.     * init ({
    47.       payload,
    48.     }, { put, call, select }) {
    49.       yield call(openWs);
    50.       const listener = yield call(onMessage);
    51.       yield put({type: 'receiveMsg', payload:{listener}});
    52.     },

    53.     // 接受消息
    54.     * receiveMsg ({
    55.         payload: {listener}
    56.     }, { call, select, put}) {
    57.         while(true){
    58.           const event = yield call(listener.message);

    59.           yield put({
    60.             type: 'progressMsg',
    61.             payload:{
    62.               msg:JSON.parse(event.data)
    63.             }
    64.           });
    65.          
    66.             
    67.         }
    68.     },

    69.     // 统筹消息
    70.     * progressMsg ({
    71.         payload: {msg}
    72.     }, { call, select, put}) {

    73.       console.log(msg)
    74.       
    75.       yield put({
    76.         type: 'addOneMessage',
    77.         payload:{
    78.           msg
    79.         }
    80.       });
    81.         
    82.     },

    83.   },
    84.   
    85.   reducers: {
    86.    
    87.     addOneMessage(state, { payload:{msg} }) {
    88.    
    89.       const msgId = nanoid()+'-'+moment().format('x');
    90.       return state.setIn(['message',msgId], fromJS({...msg,msgId}))

    91.     },

    92.     removeOneMessage(state, { payload:{msgId} }) {
    93.    
    94.       return state.deleteIn(['message',msgId])

    95.     },

    96.     clearAllMessage(state, { payload:{} }) {
    97.    
    98.       return state.setIn(['message'],Map())

    99.     },
    100.    

    101.   },
    102.   
    103. }
    复制代码
    3、Notification组件封装,结构及代码

    (1)package.json
    1. {
    2.   "name": "Notification",
    3.   "version": "0.0.0",
    4.   "private": true,
    5.   "main": "./index.js"
    6. }
    复制代码
    (2) index.less
    1. .Notification{
    2.     .btns{
    3.         padding: 0;
    4.         margin: 15px 0 0 0;
    5.         list-style: none;
    6.         width: 100%;
    7.         display: flex;
    8.         justify-content: flex-end;
    9.         li{
    10.             margin-left: 10px;
    11.         }
    12.     }
    13. }
    复制代码
    (3)index.js
    1. /**
    2. * 右下角弹窗组件封装
    3. */
    4. import React from 'react'
    5. import { injectIntl } from 'react-intl';
    6. import moment from 'moment'
    7. import { connect } from 'dva'
    8. import { notification } from 'antd';
    9. import Demo1 from './Demo1'
    10. import Demo2 from './Demo2'

    11. @injectIntl
    12. @connect(({
    13.   websocket,
    14. }) => ({
    15.   websocket
    16. }))
    17. export default class Notification extends React.Component {

    18.   componentWillReceiveProps(nextProps) {
    19.     const {websocket,dispatch,intl, intl: { formatMessage }} = nextProps;
    20.     let message=websocket.get('message');

    21.     message.forEach((note)=>{

    22.       let object=note.getIn(['object']);
    23.       let msgId=note.getIn(['msgId']);
    24.       let title=note.getIn(['title']);
    25.       let content=note.getIn(['content']);
    26.       let format = 'YYYY-MM-DD HH:mm:ss';
    27.       let time=note.getIn(['ts'])?moment(note.getIn(['ts']), 'x').format(format):moment().format(format);

    28.       switch (object) {
    29.         case 'demo1':
    30.           content=<Demo1
    31.                                                 dispatch={dispatch}
    32.                                                 intl={intl}
    33.                                                 note={note}
    34.                                                 onClose={()=>this.onClose(msgId)}
    35.                                         />;
    36.                                         break;
    37.         case 'demo2':
    38.           content=<Demo2
    39.             dispatch={dispatch}
    40.             intl={intl}
    41.             note={note}
    42.             onClose={()=>this.onClose(msgId)}
    43.           />;
    44.           break;
    45.         default:
    46.                                         break;
    47.                         }

    48.       notification.open({
    49.         message: <span>{title} <small>{time}</small></span>,
    50.         duration:30,
    51.         key: msgId,
    52.         description:content,
    53.         placement: 'bottomRight',
    54.         onClick: () => {
    55.          
    56.         },
    57.         onClose: () => {
    58.           this.onClose(msgId);
    59.         }
    60.       });
    61.     })

    62.   }

    63.   // 关闭消息
    64.   onClose=(msgId)=>{
    65.     const {dispatch} = this.props;
    66.     dispatch({
    67.       type:'websocket/removeOneMessage',
    68.       payload:{
    69.         msgId
    70.       }
    71.     })
    72.     return notification.close(msgId);
    73.   }
    74.   
    75.   render(){
    76.     return(
    77.         null
    78.     )
    79.   }
    80.   
    81. }


    82. Notification.propTypes = {
    83.   
    84. }
    复制代码
    (4)Demo1.js
    1. import React from 'react'
    2. import styles from './index.less'

    3. export default class NotificationSon extends React.Component {
    4.   
    5.   render(){
    6.     const {note,intl:{formatMessage}} = this.props;
    7.     let content=note.getIn(['content']);

    8.     return(
    9.         <div className={styles.Notification}>
    10.           <div>{content}</div>
    11.         </div>
    12.     )
    13.   }
    14.   
    15. }

    16. NotificationSon.propTypes = {
    17.   
    18. }
    复制代码
    (5)Demo2.js
    1. import React from 'react'
    2. import styles from './index.less'
    3. import { config } from 'utils'
    4. import { Button } from 'antd';

    5. const { defaultStyleSize } = config;

    6. export default class NotificationSon extends React.Component {

    7.   dealApproval=(type,data)=>{
    8.     const {dispatch,onClose} = this.props;
    9.     if(type=='refuse'){
    10.       console.log('拒绝')
    11.       onClose();
    12.     }else if(type=='agree'){
    13.       console.log('同意')
    14.       onClose();
    15.     }
    16.    
    17.   }
    18.   
    19.   render(){
    20.     const {note,intl:{formatMessage}} = this.props;
    21.     let content=note.getIn(['content']);

    22.     return(
    23.         <div className={styles.Notification}>
    24.           <div>{content}</div>
    25.           <ul className={styles.btns}>
    26.             <li>
    27.               <Button style={{ marginLeft: '12px' }} type={'primary'} size={defaultStyleSize}  onClick={() => {this.dealApproval('agree',note.get('data'))}}>{formatMessage({id: 'Global.agree'})}</Button>
    28.             </li>
    29.             <li>
    30.               <Button style={{ marginLeft: '12px' }} type={'danger'} size={defaultStyleSize}  onClick={() => {this.dealApproval('refuse',note.get('data'))}}>{formatMessage({id: 'Global.refuse'})}</Button>
    31.             </li>
    32.           </ul>
    33.         </div>
    34.     )
    35.   }
    36.   
    37. }

    38. NotificationSon.propTypes = {
    39.   
    40. }
    复制代码
    express模拟消息:

    到此这篇关于前端监听websocket消息并实时弹出的文章就介绍到这了,更多相关websocket消息监听内容请搜索脚本之家以前的文章或继续浏览下面的相关文章,希望大家以后多多支持脚本之家!

    来源:https://www.jb51.net/html5/798933.html
    免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?立即注册

    ×

    最新评论

    QQ Archiver 手机版 小黑屋 福建二哥 ( 闽ICP备2022004717号|闽公网安备35052402000345号 )

    Powered by Discuz! X3.5 © 2001-2023

    快速回复 返回顶部 返回列表