WebSocket Socket 聊天室

17 篇文章 0 订阅
1 篇文章 0 订阅

WebSocket 的简单使用 Nodejs版

WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。

WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。

现在,很多网站为了实现推送技术,所用的技术都是 Ajax 轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。

HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。

浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。

当你获取 Web Socket 连接后,你可以通过 send() 方法来向服务器发送数据,并通过 onmessage 事件来接收服务器返回的数据。

以下 API 用于创建 WebSocket 对象。

直接开始代码:

vue代码

<template>
  <div class="pages" v-loading="loading">

    <el-card class="msg" shadow="hover">
      <div class="item" v-for="(item, index) in datas.arr2" :key="index">
        <h5 :style="`color: ${item.color}`">{{item.title}}:</h5>
        {{item.messages}}
      </div>
    </el-card>

    <el-card class="msg" shadow="hover">
      <div class="item" v-for="(item, index) in datas.arr" :key="index">
        <h5 :style="`color: ${item.color}`">{{item.title}}:</h5>
        {{item.messages}}
      </div>
    </el-card>

    <el-card class="el-card-box" shadow="hover">
      <span>发送你的消息</span>
      <div></div>
      <hr>
      <el-input placeholder="请输入内容" v-model="formDatas.title" @keyup.enter="onSubmit" />
      <el-input placeholder="请输入内容" type="color" v-model="formDatas.color" />
      <el-input type="textarea" :rows="2" placeholder="请输入内容" v-model="formDatas.messages" @keyup.enter="onSubmit" />
      <p style="color: red">{{isSubmit ? '消息不合法' : ''}}</p>
      <el-button type="primary" @click="onSubmit">发送</el-button>
      <el-button type="primary" @click="createSocket">连接</el-button>
    </el-card>
  </div>
</template>

<script>
let than, socket, setIntervalCreateSocket;

export default {
  components: { animation },
  data() {
    return {
      loading: false,
      isSubmit: false,
      // 服务器不来消息 我主动询问 间隔时间
      serveTime: 0,
      toServeTime: 3,

      formDatas: {
        title: "Dwp",
        messages: "",
        color: "#000000",
      },
      arr: [],
      datas: {},
    };
  },
  computed: {},
  watch: {},
  created() {
    than = this;
    this.createSocket();
    this.loading = true;
    setTimeout(() => {
      this.loading = false;
    }, 2000);
  },
  methods: {
    createSocket() {
      // socket = new WebSocket("ws://localhost:9000");
      socket = new WebSocket("ws://121.201.2.228:10748"); // 对应nodejs服务地址
      // Listen for messages
      socket.addEventListener("message", function (event) {
        than.serveTime = 0;
        than.datas = JSON.parse(event.data);
        // console.log("Message from server ", than.datas);
      });

      // Listen for error
      socket.addEventListener("error", function (event) {
        console.log("error from server ", event.data);
        this.setIntervalCreateSocketFunc();
      });

      // 连接成功
      socket.addEventListener("open", function (event) {
        console.log("连接成功");
        than.serveTime = 0;
      });

      // Listen for close
      socket.addEventListener("close", function (event) {
        this.setIntervalCreateSocketFunc();
      });
    },
      // 定时连接
    setIntervalCreateSocketFunc() {
      clearInterval(setIntervalCreateSocket);
      setIntervalCreateSocket = setInterval(() => {
        than.serveTime++;
        if (than.serveTime >= than.toServeTime) {
          clearInterval(setIntervalCreateSocket);
          console.log("开始连接...");
          than.createSocket();
        }
      }, 1000);
    },
    async onSubmit() {
      if (this.formDatas.messages == "") {
        this.isSubmit = true;
        return;
      }
      if (
        this.formDatas.messages ==
          this.datas.arr[this.datas.arr.length - 1].messages &&
        this.formDatas.title == this.datas.arr[this.datas.arr.length - 1].title
      ) {
        this.isSubmit = true;
        return;
      }
      this.isSubmit = false;
	  // 发送数据
      socket.send(JSON.stringify(than.formDatas));
    },
  },
};
</script>
<style lang='less' scoped>
.pages {
  display: flex;
  justify-content: center;
  .el-card-box,
  .msg {
    margin: 0 4px;
    width: 400px;
  }
  .msg {
    text-align: left;
    .item {
      margin: 2px 0;
      padding: 5px 10px;
      border: solid 1px;
      border-radius: 5px;
      h5 {
        margin: 2px 0;
      }
    }
  }
}
</style>

Nodejs代码 (文件名不重要, 要跑起来)

这里要先下载 ws 模块

npm i ws
let arr = [];
let arr2 = [];
var clientStockUpdaterNum = 0;
var WebSocketServer = require('ws').Server,
  wss = new WebSocketServer({
    port: 9000
  });

wss.on('connection', function (ws) {
  var sendStockUpdates = function (ws) {
    if (ws.readyState == 1) {
      ws.send(JSON.stringify({
        arr,
        arr2
      })); //需要将对象转成字符串。WebSocket只支持文本和二进制数据
    }
  }


  clientStockUpdater = setInterval(function () {
    sendStockUpdates(ws);
  }, 2000);

  ws.on('message', function (message) {
    let stockRequest = JSON.parse(message); //根据请求过来的数据来更新。
    if (arr.length > 10) { // 处理消息过多
      arr2 = JSON.parse(JSON.stringify(arr));
      arr = [];
    }
    arr.push({
      ...stockRequest,
      num: clientStockUpdaterNum++,
      data: new Date()
    });
    console.log("收到消息", stockRequest);
    clientStocks = stockRequest['stocks'];
    sendStockUpdates(ws);
  });
})
console.log('ws://localhost:9000')

注意:

如果大家不想在vue项目里面跑, 可以自己将socket 对象的所有代码抽离出来

nodejs环境中必须下载 ws 模块

这天看了一下webSocket感觉挺有趣的,
写个dome学习一下

后续我会更加深入的学习这个知识点

觉得有用的, 点赞关注加评论

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

厚渡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值