websocket在vue2中如何封装使用

其他教程   发布日期:2023年08月14日   浏览次数:644

这篇文章主要讲解了“websocket在vue2中如何封装使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“websocket在vue2中如何封装使用”吧!

    websocket在vue2中的封装使用

    先说需求: 页面中有websocket连接,进入的时候发送参数到后端,后端发送消息, 离开页面时发送参数至后端,后端停止发送消息,不得断开连接, 下一次进入时页面时不用再次连接。

    实现思路:

    • 因为是全局连接一个websocket,所以这里采用单例模式

    • 也是因为封装的原因,页面中肯定是直接拿不到onmessage中返回的数据, 所以这里采用发布订阅模式来做

    完整代码在最后,不想看我废话的可以直接扒拉了

    步骤

    步骤就是: 连接,页面发送消息,接收消息,over ~

    首先定义连接websocket的方法

    1. export default class SocketService {
    2. constructor(url){
    3. this.url = url
    4. },
    5. connect() {
    6. //判断浏览器是否支持websocket
    7. if (!window.WebSocket) {
    8. return console.log("您的浏览器不支持WebSocket");
    9. }
    10. url,
    11. //连接websocket
    12. this.ws = new WebSocket(this.url);
    13. //监听websocket各种状态
    14. this.ws.onopen = () => {};
    15. this.ws.onclose = () => {};
    16. this.ws.onerror = () => {};
    17. this.ws.onmessage = (e) => {};
    18. }
    19. }

    我们先让socket连接上叭

    1. export default class SocketService {
    2. constructor(url againConnect = true){
    3. this.url = url
    4. this.againConnect = againConnect;
    5. },
    6. ws = null; // 和服务端连接的socket对象
    7. url; //地址
    8. againConnect; //标识断开是否重连
    9. connected = false; // 标识是否连接成功
    10. sendRetryCount = 0; // 记录重试的次数
    11. connectRetryCount = 0; // 重新连接尝试的次数
    12. connect() {
    13. //判断浏览器是否支持websocket
    14. if (!window.WebSocket) {
    15. return console.log("您的浏览器不支持WebSocket");
    16. }
    17. url,
    18. //连接websocket
    19. this.ws = new WebSocket(this.url);
    20. //监听websocket各种状态
    21. this.ws.onopen = () => {
    22. //连接上后所有标识清零
    23. this.connected = true;
    24. this.connectRetryCount = 0;
    25. };
    26. this.ws.onclose = () => {
    27. //连接关闭
    28. this.connected = false;
    29. this.connectRetryCount++;
    30. if (this.againConnect) {
    31. //重连
    32. setTimeout(() => {
    33. this.connect();
    34. }, 500 * this.connectRetryCount);
    35. } else {
    36. //不重连的操作
    37. sessionStorage.clear();
    38. localStorage.clear();
    39. message.error("登录超时");
    40. router.push("/");
    41. }
    42. };
    43. this.ws.onerror = () => {
    44. //连接失败
    45. this.connected = false;
    46. this.connectRetryCount++;
    47. if (this.againConnect) {
    48. setTimeout(() => {
    49. this.connect();
    50. }, 500 * this.connectRetryCount);
    51. }
    52. };
    53. this.ws.onmessage = (e) => {
    54. console.log(e)
    55. };
    56. },
    57. unSubscribe() {}
    58. send(){
    59. //发送消息的方法
    60. }
    61. }

    那么我们要怎么给后端发送消息呢,发送了消息之后我们又该怎样才能在页面中接收到消息呢?

    在send方法中接收一个回调函数,

    在message中调用,

    1. subscribeList = {}; //记载回调函数
    2. idList = [];
    3. send(data, callback) {
    4. //判断此时有没有ws
    5. if (!this.ws) {
    6. this.connect();
    7. this.send(data, callback);
    8. } else {
    9. // 判断此时此刻有没有连接成功
    10. if (this.connected) {
    11. this.sendRetryCount = 0;
    12. this.ws.send(JSON.stringify(data));
    13. if (data.type === "sub") {
    14. //存储id
    15. this.idList.push(data.id);
    16. //存储回调函数,
    17. if (!this.subscribeList[data.id]) {
    18. this.subscribeList[data.id] = [callback];
    19. } else {
    20. this.subscribeList[data.id].push(callback);
    21. }
    22. }
    23. } else {
    24. this.sendRetryCount++;
    25. setTimeout(() => {
    26. this.send(data, callback);
    27. }, this.sendRetryCount * 500);
    28. }
    29. }
    30. }
    31. connect(){
    32. ......
    33. this.ws.onmessage = (e) => {
    34. let { payload, requestId, type } = JSON.parse(e.data);
    35. if (type === "error") {
    36. console.log("出错了");
    37. }
    38. if (this.subscribeList[requestId]) {
    39. if (type === "complete") {
    40. console.log("完成了");
    41. } else if (type === "result") {
    42. this.subscribeList[requestId].forEach((item) =>
    43. item.call(this, payload)
    44. );
    45. }
    46. }
    47. };
    48. }
    49. //销毁回调函数
    50. unSubscribe() {
    51. //停止消息发送
    52. this.idList.forEach((item) => {
    53. this.send({ id: item, type: "unsub" });
    54. delete this.subscribeList[item];
    55. });
    56. this.idList = [];
    57. }
    • sub标识发送消息, unsub标识停止发送消息

    • id为事件的标识符

    现在解决了页面中接收消息的问题,那么怎么保证离开页面,回到页面,使用的是同一个websocket呢,如果实例化这个类的话,那么每次进入都会实例化SocketService,

    es6的class中有取值函数和存值函数, 具体使用请看这里:

    Class 的基本语法 - ES6 教程 - 网道 (wangdoc.com)

    1. instance = null;
    2. static get Instance() {
    3. if (!this.instance) {
    4. this.instance = new SocketService(false);
    5. }
    6. return this.instance;
    7. }
    • 使用getter,来拿取class中的instance,拿取的时候设置拦截该行为,判断instance有没有值,没有值就实例化SocketService给instance,返回instance,

    页面中使用方式

    1. import SocketService from "@/websocket/websocket";
    2. mounted() {
    3. this.ws = SocketService.Instance;
    4. this.ws.send(
    5. {
    6. id: "11111",
    7. topic: "/xxx/xxx",
    8. parameter: {},
    9. type: "sub",
    10. },
    11. this.Callback
    12. );
    13. }
    14. destroyed() {
    15. this.ws.unSubscribe();
    16. },
    17. methods:{
    18. Callback(data) {
    19. console.log(data);
    20. },
    21. }

    在vue中的封装

    1. export default class SocketService {
    2. constructor(againConnect = true, url) {
    3. this.url = url;
    4. this.againConnect = againConnect;
    5. }
    6. instance = null; //页面中使用的SocketService实例
    7. ws = null; // 和服务端连接的socket对象
    8. url; //地址
    9. againConnect; //断开是否重连
    10. connected = false; // 标识是否连接成功
    11. sendRetryCount = 0; // 记录重试的次数
    12. connectRetryCount = 0; // 重新连接尝试的次数
    13. //单例模式保证只有一个SocketService实例
    14. static get Instance() {
    15. if (!this.instance) {
    16. this.url = '......'
    17. this.instance = new SocketService(false, url);
    18. }
    19. return this.instance;
    20. }
    21. // 定义连接服务器的方法
    22. connect() {
    23. // 这里判断你的浏览器支不支持websocket
    24. if (!window.WebSocket) {
    25. return console.log("您的浏览器不支持WebSocket");
    26. }
    27. this.ws = new WebSocket(this.url);
    28. //连接上了
    29. this.ws.onopen = () => {
    30. this.connected = true;
    31. // 重置重新连接的次数
    32. this.connectRetryCount = 0;
    33. };
    34. //连接关闭了,设置标识值为false,
    35. this.ws.onclose = () => {
    36. this.connected = false;
    37. this.connectRetryCount++;
    38. if (this.againConnect) {
    39. setTimeout(() => {
    40. this.connect();
    41. }, 500 * this.connectRetryCount);
    42. } else {
    43. sessionStorage.clear();
    44. localStorage.clear();
    45. message.error("登录超时");
    46. router.push("/");
    47. }
    48. };
    49. this.ws.onerror = () => {
    50. console.log("socket连接失败");
    51. this.connected = false;
    52. this.connectRetryCount++;
    53. if (this.againConnect) {
    54. setTimeout(() => {
    55. this.connect();
    56. }, 500 * this.connectRetryCount);
    57. }
    58. };
    59. this.ws.onmessage = (e) => {
    60. let { payload, requestId } = JSON.parse(e.data);
    61. if (this.subscribeList[requestId]) {
    62. this.subscribeList[requestId].forEach((item) =>
    63. item.call(this, payload)
    64. );
    65. }
    66. };
    67. }
    68. //销毁回调函数
    69. unSubscribe() {
    70. //停止消息发送
    71. this.idList.forEach((item) => {
    72. this.send({ id: item, type: "unsub" });
    73. delete this.subscribeList[item];
    74. });
    75. this.idList = [];
    76. }
    77. subscribeList = {}; //记载回调函数
    78. idList = [];
    79. // 发送数据的方法
    80. send(data, callback) {
    81. //判断此时有没有ws
    82. if (!this.ws) {
    83. this.connect();
    84. this.send(data, callback);
    85. } else {
    86. // 判断此时此刻有没有连接成功
    87. if (this.connected) {
    88. this.sendRetryCount = 0;
    89. this.ws.send(JSON.stringify(data));
    90. if (data.type === "sub") {
    91. //存储id
    92. this.idList.push(data.id);
    93. //存储回调函数,
    94. if (!this.subscribeList[data.id]) {
    95. this.subscribeList[data.id] = [callback];
    96. } else {
    97. this.subscribeList[data.id].push(callback);
    98. }
    99. }
    100. } else {
    101. this.sendRetryCount++;
    102. setTimeout(() => {
    103. this.send(data, callback);
    104. }, this.sendRetryCount * 500);
    105. }
    106. }
    107. }
    108. }

    以上就是websocket在vue2中如何封装使用的详细内容,更多关于websocket在vue2中如何封装使用的资料请关注九品源码其它相关文章!