前端SSE 通信

173 阅读1分钟

nodejs 模拟一个sse 服务

const http = require('http');

const server = http.createServer((req, res) => {
  if (req.url === '/events') {
    res.setHeader('Content-Type', 'text/event-stream');
    res.setHeader('Cache-Control', 'no-cache');
    res.setHeader('Connection', 'keep-alive');
    res.flushHeaders();

    // 发送消息的函数
    const sendMessage = (message) => {
      res.write(`data: ${JSON.stringify(message)}\n\n`);
    };

    // 定时发送消息
    const intervalId = setInterval(() => {
      sendMessage({ time: new Date().toISOString(), message: 'Hello, SSE!' });
    }, 1000);

    // 当客户端关闭连接时
    req.on('close', () => {
      clearInterval(intervalId);
      res.end();
    });
  } else {
    res.writeHead(404);
    res.end();
  }
});

server.listen(3000, () => {
  console.log('SSE server is running on http://localhost:3000/events');
});

<script src="https://cdn.bootcss.com/event-source-polyfill/0.0.9/eventsource.min.js"></script>
<script>
/*
 上面的js 是不必引入的 ,直接测试 可以使用 hbuider的支持跨域的浏览器打开html
*/

      this.eventSource = new EventSource('http://192.168.0.134:3000/events');
    
      this.eventSource.onmessage = (event) => { 
        console.log(event.data); 
      };
      this.eventSource.onerror = (error) => {
        console.error('SSE error:', error);
        this.eventSource.close();
      };

</script>

uniapp 手机端不支持 EventSource 而且不支持 headers 参数 , renderjs 可以解决这个问题 "event-source-polyfill": "^1.0.31",

 <template>
  <view :prop="gptStr" 
	:change:prop="renderScript.onChange" 
        id="renderjs-view"
	@click="renderScript.emitData" ></view>
</template>
<script module="renderScript" lang="renderjs">
import { EventSourcePolyfill } from 'event-source-polyfill';
export default {
  data() {
    return { 
      IsSupportSse: 'EventSource' in window,
      source: null,
    };
  },
  created() {
  	console.log("created() ")
  },
  methods: {
    onChange(newValue, oldValue, ownerInstance, instance) { 
      var { token,uuid} = JSON.parse(newValue)
      if (newValue['gptStrText'] !== '') {
        if (this.source) this.source.close(); 
	 this.sse('http://192.168.0.134:3000/events', token,uuid);
      }
    },
    // SSE连接方法
    sse(url, token,uuid) { 
       var x = this.$ownerInstance.callMethod('getTmp') 
       if (!this.IsSupportSse) return;
       this.source = new EventSourcePolyfill(url,{  headers:{ token, uuid }  }); 
      this.source.onmessage = (e) => { 
        console.log('收到服务器消息:', e.data);
	 this.emitData(e.data)
      };
    },
    // 向逻辑层发送数据
    emitData(data) {
      this.$ownerInstance.callMethod('receiveRenderData', data);
    }
  }
}
</script>
<script> 
	var res
	export default {
		data() {
			return { 
				gptStr:'', 
			}
		},
		  
		async onShow() { 
		   var res = await uni.post("/api/login/phonePwd",{"userPhone": "", "password": "",}) 
		  this.gptStr = JSON.stringify(res)
			 
			
		},
		 
		methods: {  
			receiveRenderData(data) { 
			    this.viewData = data;
			    console.log("VUE" ,data);
			},
			 
		}
	}
</script>