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


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

    1、前端部分 websocket 代码

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

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

    一、前端部分 websocket 代码

    1. <script>
    2. export default {
    3. name: 'App',
    4. data() {
    5. return {
    6. messages: [],
    7. newMessage: '',
    8. socket: null,
    9. };
    10. },
    11. created() {
    12. this.initializeWebSocketConnection();
    13. },
    14. beforeDestroy() {
    15. if (this.socket) {
    16. this.socket.close();
    17. }
    18. },
    19. methods: {
    20. initializeWebSocketConnection() {
    21. // 建立连接
    22. this.socket = new WebSocket('ws://localhost:8083');
    23. // 客户端向服务端发送消息
    24. this.socket.onopen = () => {
    25. this.socket.send(
    26. JSON.stringify({
    27. value: this.newMessage,
    28. })
    29. );
    30. };
    31. // 客户端接收服务端的消息
    32. this.socket.onmessage = (event) => {
    33. const res = JSON.parse(event.data);
    34. this.messages.push(res.data);
    35. };
    36. // 错误处理
    37. this.socket.onerror = (error) => {
    38. console.error('WebSocket Error:', error);
    39. };
    40. // 关闭
    41. this.socket.onclose = () => {
    42. console.log('WebSocket connection closed');
    43. };
    44. },
    45. sendMessage() {
    46. // 手动向服务端发送消息
    47. if (this.socket.readyState === WebSocket.OPEN) {
    48. this.socket.send(
    49. JSON.stringify({
    50. value: this.newMessage,
    51. })
    52. );
    53. this.newMessage = '';
    54. } else {
    55. console.error('Cannot send message, the socket is not open.');
    56. }
    57. },
    58. },
    59. };
    60. script>
    61. <style>
    62. #app {
    63. font-family: Avenir, Helvetica, Arial, sans-serif;
    64. -webkit-font-smoothing: antialiased;
    65. -moz-osx-font-smoothing: grayscale;
    66. text-align: center;
    67. color: #2c3e50;
    68. }
    69. 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 中看到消息推送,当客户端和服务端建立连接之后,客户端可以向服务端发送消息,服务端也可以向客户端推送消息,实现即时通信功能。如下图:

  • 相关阅读:
    VUE项目中页面权限和按钮权限
    web前端设计与开发期末作品 旅游咨询网站 HTML5期末大作业 HTML+CSS旅游社网站5个页面 关于制作网页主题论述
    webpack学习笔记
    labuladong算法小抄-数据结构设计-leetcode146、leetcode341、leetcode380、leetcode460
    少儿编程 电子学会图形化 scratch编程等级考试四级真题答案解析(选择题)2022年9月
    使用numpy计算相关系数矩阵:np.corrcoef()
    享元模式Flyweight
    【微服务十一】SpringCloud之OpenFeign的常用配置(超时、数据压缩、日志、重试等)
    基于Docker来部署Nacos的注册中心
    git常用命令汇总
  • 原文地址:https://blog.csdn.net/qq_37309987/article/details/137924048