0


Socket.io 是什么,如何使用,与 WebSocket 的关系?

Socket.io 是什么,如何使用,与 WebSocket 的关系?

介绍

上篇我们讲到了 WebSocket 的使用,不太了解的小伙伴,建议先到我上篇文章了解下再来学习。

Socket.io是一个建立在 WebSocket 协议之上的库,他提供了低延迟、双向通信、基于事件(可以自定义双方约定好的事件)的功能,保证了使用中的稳定性和兼容性,比如用户使用的浏览器版本不支持,会使用 HTTP长轮询 实现:断线自动重连的功能。

与 WebSocket 区别

  • Socket.io 虽然建立在 WebSocket 协议之上,但不是 WebSocket 的实现。
  • 目前仍有些许浏览器无法建立WebSocket连接,使用 Socket.io 可以做兼容性处理,转为 HTTP长轮询
  • 服务器和客户端之间的WebSocket连接可能会中断,双方都不知道连接的中断状态。Socket.io 自带一个心跳机制,它可以定期检查连接的状态,WebSocket 需要手动实现。
  • 虽然 Socket.io 确实是在客户端支持的情况下使用 WebSocket 进行传输,但是它为每个数据包添加了额外的 元数据。这就是 WebSocket 客户端无法成功连接到 Socket.io 服务端,Socket.io 客户端也无法连接到普通的WebSocket服务器的原因。所以双方要同时规定好使用 websocket 还是 Socket.io,不能混用。
  • Socket.io 提供了支持派发事件和监听时间的便捷功能,以下是官网案例:
socket.emit("hello","world",(response)=>{
  console.log(response);// "got it"});
socket.on("hello",(arg, callback)=>{
  console.log(arg);// "world"callback("got it");});

上面代码中的"hello"就是双方约定好的事件,平常项目开发中一般会在前面加上 $,表示自定义事件。

  • Socket.io 还提供了方便快捷的广播方式
// socket.io
io.on("connection",(socket)=>{
  socket.broadcast.emit("hello","world");});// 原生 websocket
socket.on('message',(message)=>{
  ws.clients.forEach((client)=>{
    client.send({type:"hello",
      message
    });})})

使用 Socket.io 实现一个简易聊天室

  • 我这里前端使用 vue3+TS,后端 node(这是肯定的,只支持node)
  • 先看成品展示,简单做了一下,样式请不要在乎。。。在这里插入图片描述在这里插入图片描述
  • 以下是代码部分
  • 前端- html
<template><divclass="container"><divclass="users-area"><!-- 待开发,感兴趣自己可以试着做做 --><inputtype="text"placeholder="搜索"><ulclass="users-list"><liv-for="u in users":key="u">{{ u }}</li></ul></div><divclass="msg-area"><divclass="message-area"><divclass="item":class="{ self: self === item.name }"v-for="(item, ind) in msgList":key="ind"><spanclass="name">{{ item.name }}</span><pclass="message">{{ item.message }}</p></div></div><divclass="input-area"><textareav-model="message"@keydown.enter="sendMsg"></textarea></div></div></div></template>
  • TS
<script setup lang="ts">import{ defineProps, watch, ref, defineEmits }from'vue';const message =ref('');const emits =defineEmits(['chat'])typeProps={
  users?:any[];
  msgList?:{ name:string, message:string}[];
  self:string}const props =withDefaults(defineProps<Props>(),{users:()=>[],msgList:()=>[]})constsendMsg=()=>{const val = message.value.trim();if(val){
    message.value ='';emits('chat',{ name: props.self, message: val });}}</script>
  • CSS
<style scoped>
.container{display: flex;width: 550px;height: 500px;border-radius: 8px;box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);background-color:rgb(235, 235, 235);overflow: hidden;}.users-area{width: 150px;border-right: 1px solid #ccc;line-height: 30px;overflow: auto;flex: 0 0 auto;}.users-area input{margin-top: 10px;width: 80%;border: none
}.users-area input:focus{outline: 1px solid #aaa
}.users-area p{text-align: center;border-bottom: 1px solid #ccc;}.users-area .users-list{padding: 0;margin: 10px 0;list-style: none;border-top: 1px solid #ccc;}.users-list li{padding: 0 10px;margin: 10px 0;font-size: 12px;border-bottom: 1px solid #ccc;background:rgb(220, 220, 220);}.msg-area{display: flex;flex-direction: column;flex: 1;background-color:rgb(245, 245, 245);}.message-area{height: 75%;padding: 1em;font-size: 14px;line-height: 1.3;overflow-y: scroll;}.item{float: left;max-width: 70%;clear: both;margin-bottom: 1em;}.name{font-size: 12px;color: #333;}.message{border-radius: 6px;padding: 10px;margin: 4px 0;background-color: #fff
}.item.self{float: right;}.self .message{background-color:rgb(137, 217, 97);}.self .name{text-align: right;}.input-area{flex: 1;border-top: 1px solid #ccc;}.input-area textarea{width: 100%;height: 100%;padding: 10px 20px;border: none;outline: none;}
</style>
  • 上面是子组件(聊天框),以下是父组件逻辑
<template><WeChat :self="self":msgList="msgList":users="users"@chat="handleChat"/></template><script setup lang='ts'>import WeChat from'@/components/WeChat.vue';import{ io, Socket }from'socket.io-client';import{ ref, onMounted, onUnmounted }from'vue';interfaceIChatContent{
  name:string;
  message:string}const msgList =ref<IChatContent[]>([]);const users =ref<string[]>([]);const self =ref('');const socket =ref<Socket |null>(null);onMounted(()=>{
  socket.value =io('http://localhost:3000');// 接受消息
  socket.value.on('$messages',(data: IChatContent)=>{
    msgList.value.push(data);});// 监听加入聊天室的用户
  socket.value.on('$users',(data:string[])=>{
    users.value = data;});// 监听其他人发送的消息
  socket.value.on('$msgList',(data: IChatContent[])=>{
    msgList.value = data;});})consthandleChat=(data: IChatContent)=>{
  msgList.value.push(data);// 将当前聊天内容发送给服务器,通知其他人(socket.value as Socket).emit('$messages', data.message);}/**
 * 组件卸载时断开连接
 */onUnmounted(()=>{(socket.value as Socket).disconnect();})</script>
  • node 端
import{ Server }from"socket.io";const io =newServer({path:'/',cors:'*'});const usersList =[];// 用户集合const chatContentList =[];// 消息体集合let ind =0;// 记录当前是第几位成员(做简单区分)

io.on("connection",(socket)=>{const userName ='成员'+++ind;
  usersList.push(userName);// 加入新成员并告知客户端(这里不能广播,因为广播不包括自己)
  socket.emit('$users', usersList);
  socket.on('$messages',(message)=>{const content ={name: userName,
      message
    }
    chatContentList.push(content);// 给所有用户发送当前用户发来的消息
    socket.broadcast.emit('$messages', content);})// 监听到连接关闭
  socket.on('disconnect',()=>{// 清除用户
    usersList.splice(usersList.indexOf(userName),1);// 广播通知所有用户
    socket.broadcast.emit('$users', usersList);});});

io.listen(3000);
标签: 网络 前端 node.js

本文转载自: https://blog.csdn.net/weixin_56241259/article/details/140766620
版权归原作者 Liquor~~ 所有, 如有侵权,请联系我们删除。

“Socket.io 是什么,如何使用,与 WebSocket 的关系?”的评论:

还没有评论