websocket 请求头报错 Provisional headers are shown 的解决方法

今日简单总结 websocket 使用过程中遇到的问题,主要从以下三个方面来分享:

1、前端部分 websocket 代码

2、使用 koa.js 实现后端 websocket 服务搭建

3、和后端 java Netty 库对接时遇到连接失败问题

一、前端部分 websocket 代码


   
   
  1. <template>
  2. <div id="app">
  3. <div v-for="item in messages" :key="item.id">
  4. {{ item.value }}
  5. </div>
  6. <el-form :inline="true">
  7. <el-form-item label="消息:">
  8. <el-input v-model="newMessage" placeholder="请输入内容"> </el-input>
  9. </el-form-item>
  10. <el-form-item>
  11. <el-button type="primary" @click="sendMessage">发送 </el-button>
  12. </el-form-item>
  13. </el-form>
  14. <router-view />
  15. </div>
  16. </template>
  17. <script>
  18. export default {
  19. name: 'App',
  20. data( ) {
  21. return {
  22. messages: [],
  23. newMessage: '',
  24. socket: null,
  25. };
  26. },
  27. created( ) {
  28. this. initializeWebSocketConnection();
  29. },
  30. beforeDestroy( ) {
  31. if ( this. socket) {
  32. this. socket. close();
  33. }
  34. },
  35. methods: {
  36. initializeWebSocketConnection( ) {
  37. // 建立连接
  38. this. socket = new WebSocket( 'ws://localhost:8083');
  39. // 客户端向服务端发送消息
  40. this. socket. onopen = () => {
  41. this. socket. send(
  42. JSON. stringify({
  43. value: this. newMessage,
  44. })
  45. );
  46. };
  47. // 客户端接收服务端的消息
  48. this. socket. onmessage = (event) => {
  49. const res = JSON. parse(event. data);
  50. this. messages. push(res. data);
  51. };
  52. // 错误处理
  53. this. socket. onerror = (error) => {
  54. console. error( 'WebSocket Error:', error);
  55. };
  56. // 关闭
  57. this. socket. onclose = () => {
  58. console. log( 'WebSocket connection closed');
  59. };
  60. },
  61. sendMessage( ) {
  62. // 手动向服务端发送消息
  63. if ( this. socket. readyState === WebSocket. OPEN) {
  64. this. socket. send(
  65. JSON. stringify({
  66. value: this. newMessage,
  67. })
  68. );
  69. this. newMessage = '';
  70. } else {
  71. console. error( 'Cannot send message, the socket is not open.');
  72. }
  73. },
  74. },
  75. };
  76. </script>
  77. <style>
  78. #app {
  79. font-family: Avenir, Helvetica, Arial, sans-serif;
  80. -webkit- font-smoothing: antialiased;
  81. -moz-osx- font-smoothing: grayscale;
  82. text-align: center;
  83. color: #2c3e50;
  84. }
  85. </style>

二、使用 koa.js 实现后端 websocket 服务搭建


   
   
  1. // app.js
  2. const Koa = require( 'koa');
  3. const WebSocket = require( 'ws');
  4. const { v4: uuidv4 } = require( 'uuid');
  5. const app = new Koa();
  6. const wss = new WebSocket. Server({
  7. port: 8083,
  8. });
  9. // 存储所有连接的客户端
  10. const clients = new Set();
  11. wss. on( 'connection', (ws) => {
  12. // 新客户端连接时添加到clients集合中
  13. clients. add(ws);
  14. console. log( 'WebSocket connection opened');
  15. ws. on( 'message', (message) => {
  16. console. log( 'Received message from client:', message);
  17. try {
  18. console. log( 'clients::', clients);
  19. // 将接收到的字符串转换为JSON对象
  20. const data = JSON. parse(message);
  21. // 在此处处理接收到的JSON数据
  22. console. log( 'Received data:', data);
  23. const response = {
  24. status: '200',
  25. message: 'success',
  26. data: {
  27. id: uuidv4(),
  28. value: data. value,
  29. },
  30. };
  31. // 将响应的JSON对象转换为字符串并通过WebSocket发送
  32. ws. send( JSON. stringify(response));
  33. } catch (error) {
  34. console. error( 'Error parsing JSON:', error);
  35. // 如果解析失败,发送错误消息回客户端
  36. ws. send( JSON. stringify({ error: 'Invalid JSON format' }));
  37. }
  38. });
  39. ws. on( 'close', () => {
  40. // 客户端关闭连接时从clients集合中移除
  41. clients. delete(ws);
  42. console. log( 'WebSocket connection closed');
  43. });
  44. ws. on( 'error', (error) => {
  45. console. error( 'WebSocket error:', error);
  46. });
  47. });
  48. // 假设这个函数会在数据状态改变时被调用
  49. function onDataStateChange( newData) {
  50. // 遍历所有客户端连接并发送消息
  51. for ( const client of clients) {
  52. if (client. readyState === WebSocket. OPEN) {
  53. client. send(
  54. JSON. stringify({
  55. status: '200',
  56. message: 'success',
  57. data: {
  58. id: uuidv4(),
  59. value: '数据发生改变啦...',
  60. },
  61. })
  62. ); // 发送新数据到客户端
  63. }
  64. }
  65. }
  66. // 示例:模拟数据状态改变并推送消息
  67. setTimeout( () => {
  68. const newData = { status: 'updated', value: 'New Value' };
  69. onDataStateChange(newData); // 模拟数据状态改变,并向所有客户端推送消息
  70. }, 10000); // 5秒后模拟数据改变
  71. app. use( async (ctx) => {
  72. ctx. body = 'Hello, Koa!';
  73. });
  74. app. listen( 3000, () => {
  75. console. log( 'Server is running on port 3000');
  76. });

三、和后端 java Netty 库对接时遇到连接失败问题

前端在 1、2 步骤的验证时,websocket 成功建立连接,消息可以正常发送,但是在和后端小伙伴联调时,请求头一直报 Provisional headers are shown 错误,如下图:

原因,后端 java 在使用 Netty 库创建 webSocket 通信时,未添加协议处理器,当后端添加完协议处理器后,前端在进行通信的时候,需要在加上这个前缀,如下图:

前端的修改,如下图:

解决之后的请求头:

可以在 Messages 中看到消息推送,当客户端和服务端建立连接之后,客户端可以向服务端发送消息,服务端也可以向客户端推送消息,实现即时通信功能。如下图:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值