当前位置:   article > 正文

webSocket_js websocket readystate

js websocket readystate

介绍:

readyState表示连接有四种状态:

  1. connecting (0):表示还没建立连接;

  2. open    (1): 已经建立连接,可以进行通讯;

  3. closing (2):通过关闭握手,正在关闭连接;

  4. closed  (3):连接已经关闭或无法打开; 

前端代码表示

原生JS(HTML+JS)

HTML文件

  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>通信</title>
  6. </head>
  7. <body>
  8. <ul id="list"></ul>
  9. <input type="text" id="message" placeholder="请输入内容" />
  10. <button id="send">发送</button>
  11. <script src="XXX.js> </script>
  12. </body>
  13. </html>

JS文件

  1. //立即执行函数,避免全局变量之间的污染
  2. ;((doc)=>{
  3. const oList=doc.querySelector('#list');
  4. const oMsg=doc.querySelector('#message');
  5. const oSendBtn.querySelector('#send');
  6. const ws=new Socket('ws:localhost:8000');//创建一个Socket实例
  7. //初始化函数
  8. const init=()=>{
  9. bindEvent();
  10. }
  11. //绑定事件函数,监听oSendBtn,
  12. //最后参数是指定事件是否在捕获或冒泡阶段执行,false是默认冒泡阶段执行,true捕获阶段执行
  13. function bindEvent(){
  14. oSendBtn.addEventListener('click',handSendBtnClick,false);
  15. ws.addEventListener('open',handOpen,false);
  16. ws.addEventListener('close',handClose,false);
  17. ws.addEventListener('error',handError,false);
  18. ws.addEventListener('message',handMessage,false);
  19. }
  20. //具体的点击事件
  21. function handSendBtnClick(){
  22. console.log('发送的具体消息')
  23. const msg=oMsg.value
  24. if(!msg.trim().length){
  25. return
  26. }
  27. //发送的应该为字符串
  28. ws.send(JSON.stringfy({
  29. dataTime:new Data().getTime(),
  30. message:msg
  31. }))
  32. oMsg.value=''
  33. }
  34. //socket的四个事件
  35. function handOpen(){
  36. console.log('打开')
  37. }
  38. function handClose(){
  39. console.log('关闭')
  40. }
  41. function handError(){
  42. console.log('')
  43. }
  44. function handMessage(e){
  45. console.log('接收消息',e.data)
  46. const msgData=JSON.parse(e.data) //转化为对象
  47. oList.appendChild(createMsg(msgData)) //转为li
  48. }
  49. //做成LI的格式
  50. function createMsg(data){
  51. const {user,dataTime,message}=data
  52. const oItem=doc.createElement('li')
  53. oItem.innerHTML=`
  54. <p>
  55. <span>${user}</span>
  56. <li>${new Data()}</li>
  57. </p>
  58. <p>消息:${message}</p>
  59. `
  60. return oItem
  61. }
  62. init()
  63. })(document);

​​​​​​​纯HTML

  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>聊天室</title>
  6. <script type="text/javascript">
  7. var ws = null;
  8. var interval = null;
  9. var uri = "ws://192.168.110.92:8080/schedule/websocket/connect";
  10. var myVar = null;
  11. var reconnectState = null;
  12. function WebSocketTest() {
  13. if ("WebSocket" in window) {
  14. createWebSocket();
  15. } else {
  16. // 浏览器不支持 WebSocket
  17. alert("您的浏览器不支持 WebSocket!");
  18. }
  19. }
  20. /**
  21. * 创建websocket
  22. */
  23. function createWebSocket() {
  24. alert("开启长连接")
  25. // 打开一个 web socket
  26. ws = new WebSocket(uri);
  27. ws.onopen = function () {
  28. document.getElementById("reconnectShow").innerText = "无";
  29. document.getElementById("online").innerText = "在线";
  30. reconnectState = false;
  31. clearInterval(myVar);
  32. // 心跳检测
  33. interval = setInterval(function () {
  34. // 使用 send() 方法发送数据
  35. sendMsg("ping");
  36. }, 5000);
  37. };
  38. ws.onmessage = function (evt) {
  39. var received_msg = evt.data;
  40. console.log("回复",evt.data);
  41. if (received_msg == "pong") {
  42. console.log(received_msg);
  43. } else {
  44. document.getElementById("num").innerText = received_msg;
  45. }
  46. };
  47. ws.onclose = function () {
  48. webscoketClose();
  49. };
  50. }
  51. /**
  52. * websocket重连
  53. */
  54. function reconnect() {
  55. // 检测到websocket连接断开
  56. // 0 (WebSocket.CONNECTING)正在链接中
  57. // 1 (WebSocket.OPEN)已经链接并且可以通讯
  58. // 2 (WebSocket.CLOSING) 连接正在关闭
  59. // 3 (WebSocket.CLOSED)连接已关闭或者没有链接成功
  60. if (reconnectState == false) {
  61. reconnectState = true;
  62. var reconnectNum = 1;
  63. console.log(ws.readyState);
  64. myVar = setInterval(function () {
  65. if (ws.readyState == 2 || ws.readyState == 3) {
  66. if (reconnectNum == 6) {
  67. clearInterval(myVar);
  68. document.getElementById("reconnectShow").innerText = "停止重连";
  69. return;
  70. }
  71. document.getElementById("reconnectShow").innerText = "第" + reconnectNum + "次尝试重连中";
  72. createWebSocket();
  73. reconnectNum++;
  74. }
  75. }, 5 * 1000)
  76. }
  77. }
  78. function noReconnectclose() {
  79. reconnectState = true;
  80. webscoketClose();
  81. }
  82. /**
  83. * websocket关闭
  84. */
  85. function webscoketClose() {
  86. ws.close();
  87. clearInterval(interval)
  88. console.log("websocket关闭");
  89. document.getElementById("online").innerText = "离线";
  90. // 开启断线重连
  91. reconnect();
  92. }
  93. function sendMsg(str) {
  94. if (ws.readyState == 1) {
  95. ws.send(str);
  96. // alert("发送内容");
  97. } else {
  98. alert("未连接上服务器");
  99. }
  100. }
  101. function add() {
  102. sendMsg("+1");
  103. }
  104. function remove() {
  105. sendMsg("-1");
  106. }
  107. </script>
  108. </head>
  109. <body>
  110. <div id="sse">
  111. <a href="javascript:WebSocketTest()">运行 WebSocket</a>
  112. <a href="javascript:noReconnectclose()">停止 WebSocket</a>
  113. </div>
  114. <br>
  115. 当前webscoket状态:<span id="online">离线</span>
  116. <br>
  117. 当前重连状态:<span id="reconnectShow"></span>
  118. <br>
  119. 当前怒气值:<span id="num">0</span>
  120. <br>
  121. <a href="javascript:add()">+1</a>
  122. <a href="javascript:remove()">-1</a>
  123. </body>
  124. </html>

vue简单的逻辑 

客户端页面:

  1. <div id="app" >
  2. <ul>
  3. <li v-for="item in msgList" :key="item.id">
  4. <p>
  5. <span>{{item.username}}:</span>
  6. <span>{{new Date(item.dataTime)}}</span>
  7. </p>
  8. <p>消息:{{item.msg}}</p>
  9. </li>
  10. </ul>
  11. <input type="text" placeholder="请输入消息" v-model="msg" />
  12. <button @click="sendMsg">发送</button>
  13. </div>
  1. <script>
  2. const ws = new WebSocket('ws://localhost:8000')
  3. new Vue({
  4. el: '#app',
  5. data: {
  6. msg: '',
  7. username: '',
  8. msgList: []
  9. },
  10. mounted() {
  11. ws.addEventListener('open', this.handleWsOpen.bind(this), false) // 监听连接打开 前面的this指向绑定的ws,bind里面的this为了改变指向,指向当前vue实例
  12. ws.addEventListener('close', this.handleWsClose.bind(this), false) // 监听连接关闭
  13. ws.addEventListener('error', this.handleWsError.bind(this), false) // 监听连接错误
  14. ws.addEventListener('message', this.handleWsMessage.bind(this), false) // 监听消息
  15. },
  16. methods: {
  17. sendMsg() {
  18. //把绑定的消息取出来
  19. const msg=this.msg
  20. //如果去掉两边空格,长度还为0,则返回不再进行下一步
  21. if(!msg.trim().length){
  22. return
  23. }
  24. //把当前时间戳
  25. const dataTime=new Date().getTime()
  26. //把用户名
  27. const username=this.username
  28. //把消息发送到服务器
  29. ws.send(JSON.stringify({
  30. msg,
  31. dataTime,
  32. username
  33. }))
  34. //不可以传对象 要转化为JSON字符串
  35. // ws.send({
  36. // id:new Data().getTime(),
  37. // user:this.username,
  38. // dataTime:new Data().getTime(),
  39. // msg:this.msg
  40. // })
  41. this.msg='' //注意发送完要清空输入框
  42. },
  43. handleWsOpen(e) {
  44. console.log('连接成功')
  45. },
  46. handleWsClose(e) {
  47. console.log('连接关闭')
  48. },
  49. handleWsError(e) {
  50. console.log('连接错误')
  51. },
  52. handleWsMessage(event) {
  53. const data = JSON.parse(event.data) //内容包裹在data中 且需要转换为对象
  54. this.msgList.push(data)
  55. console.log(data)
  56. }
  57. }
  58. })
  59. </script>

 服务器部分:

增加长连接的方式 :

  1. <template>
  2. <ul>
  3. <li v-for="item in msgList" :key="item.id">
  4. <p>
  5. <span>{{item.username}}:</span>
  6. <span>{{new Date(item.dataTime)}}</span>
  7. </p>
  8. <p>消息:{{item.msg}}</p>
  9. </li>
  10. </ul>
  11. <input type="text" placeholder="请输入消息" v-model="msg" />
  12. <button @click="sendDataToServer">发送</button>
  13. </template>
  14. <script>
  15. export default {
  16. name: "WebSocket",
  17. data() {
  18. return {
  19. wsIsRun: false, // ws是否启动
  20. webSocket: null, // 定义ws对象
  21. ws: '', // ws请求链接(类似于ws后台地址)
  22. wsTimer: null, // ws定时器
  23. msg: '',
  24. username: '',
  25. msgList: [], //包含传过去的id,username,dataTime
  26. }
  27. },
  28. async mounted() {
  29. this.wsIsRun = true
  30. this.wsInit()
  31. },
  32. methods: {
  33. sendDataToServer() {
  34. if (this.webSocket.readyState === 1) {
  35. // this.webSocket.send('来自前端的数据')
  36. //把绑定的消息取出来
  37. const msg = this.msg
  38. //如果去掉两边空格,长度还为0,则返回不再进行下一步
  39. if (!msg.trim().length) {
  40. return
  41. }
  42. //当前时间戳
  43. const dataTime = new Date().getTime()
  44. //用户名
  45. const username = this.username
  46. //把消息发送到服务器
  47. this.webSocket.send(JSON.stringify({
  48. msg,
  49. dataTime,
  50. username
  51. }))
  52. this.msg = '' //注意发送完要清空输入框
  53. } else {
  54. throw Error('服务未连接')
  55. }
  56. },
  57. /**
  58. * 初始化ws
  59. */
  60. wsInit() {
  61. const wsuri = 'ws://10.229.36.158:7777/websocket/badao'
  62. this.ws = wsuri
  63. if (!this.wsIsRun) return
  64. // 销毁ws
  65. this.wsDestroy()
  66. // 初始化ws
  67. this.webSocket = new WebSocket(this.ws)
  68. // ws连接建立时触发
  69. this.webSocket.addEventListener('open', this.wsOpenHanler)
  70. // ws服务端给客户端推送消息
  71. this.webSocket.addEventListener('message', this.wsMessageHanler)
  72. // ws通信发生错误时触发
  73. this.webSocket.addEventListener('error', this.wsErrorHanler)
  74. // ws关闭时触发
  75. this.webSocket.addEventListener('close', this.wsCloseHanler)
  76. // 检查ws连接状态,readyState值为0表示尚未连接,
  77. // 1表示建立连接,2正在关闭连接,3已经关闭或无法打开
  78. clearInterval(this.wsTimer)
  79. this.wsTimer = setInterval(() => {
  80. if (this.webSocket.readyState === 1) {
  81. clearInterval(this.wsTimer)
  82. } else {
  83. console.log('ws建立连接失败')
  84. this.wsInit()
  85. }
  86. }, 3000)
  87. },
  88. wsOpenHanler(event) {
  89. console.log('ws建立连接成功')
  90. },
  91. wsMessageHanler(e) {
  92. console.log(e)
  93. const data = JSON.parse(e.data) //内容包裹在data中 且需要转换为对象
  94. this.msgList.push(data)
  95. },
  96. /**
  97. * ws通信发生错误
  98. */
  99. wsErrorHanler(event) {
  100. console.log(event, '通信发生错误')
  101. this.wsInit()
  102. },
  103. /**
  104. * ws关闭
  105. */
  106. wsCloseHanler(event) {
  107. console.log(event, 'ws关闭')
  108. this.wsInit()
  109. },
  110. /**
  111. * 销毁ws
  112. */
  113. wsDestroy() {
  114. if (this.webSocket !== null) {
  115. this.webSocket.removeEventListener('open', this.wsOpenHanler)
  116. this.webSocket.removeEventListener('message', this.wsMessageHanler)
  117. this.webSocket.removeEventListener('error', this.wsErrorHanler)
  118. this.webSocket.removeEventListener('close', this.wsCloseHanler)
  119. this.webSocket.close()
  120. this.webSocket = null
  121. clearInterval(this.wsTimer)
  122. }
  123. },
  124. }
  125. }
  126. </script>
  127. <style scoped>
  128. </style>

页面布局:

:style="i.userId == userId? 'float: right' : '' "   

:class="i.userId == userId? 'right':'left'"  

可用于区分聊天内容在左侧还是右侧

  1. .left {
  2. background: white;
  3. animation: toLeft 0.5s ease both 1;
  4. }
  5. .right {
  6. background: #53a8ff;
  7. color: white;
  8. animation: toright 0.5s ease both 1;
  9. }
  10. @keyframes toLeft {
  11. 0% {
  12. opacity: 0;
  13. transform: translateX(-10px);
  14. }
  15. 100% {
  16. opacity: 1;
  17. transform: translateX(0px);
  18. }
  19. }
  20. @keyframes toright {
  21. 0% {
  22. opacity: 0;
  23. transform: translateX(10px);
  24. }
  25. 100% {
  26. opacity: 1;
  27. transform: translateX(0px);
  28. }
  29. }
  30. }
  31. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/964304?site
推荐阅读
相关标签
  

闽ICP备14008679号