当前位置:   article > 正文

websocket使用

websocket使用

一、服务端:

1、koa2中使用websocket

1、安装ws

npm i ws -S
  • 1

2、使用

  1. 创建对象
  2. 监听连接事件
  3. 监听数据接收事件
  4. 发送数据

在app.js中添加如下代码:

//4、websocket的使用
//引入websocket
const WebSocket=require('ws')
//4-1、创建对象,绑定端口
const wss=new WebSocket.Server({
  port:9998
});
//4-2、监听连接事件
wss.on('connection',(client)=>{
  console.log("客户端连接成功。。。");
  //4-3、监听接收消息事件
  client.on('message',(msg)=>{
    console.log("接收到来着客户端的信息:"+msg);
    //模拟客户端往服务端发送数据
    client.send("hello websocket!i am app.js")
  })
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

3、测试

  • websocket是window对象提供了的,不用下载依赖可以直接使用
  1. 创建对象
  2. 监听事件(连接成功事件ws.onopen、接收数据事件ws.onmessage、关闭连接事件ws.onclose
  3. 发送数据到服务端ws.send

测试 一下,新建文件demo.html放在app.js同一级,代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <button id="connId">连接</button>
  <button id="sendId" disabled="true">发送</button></br>
  接收到的信息:<span id="msgId"></span>
</body>
<script>
  var conn=document.getElementById('connId')
  var send=document.getElementById('sendId')
  var msgId=document.getElementById('msgId')
  var ws=null
  conn.onclick=function(){
    ws=new WebSocket("ws://localhost:9998")
    ws.onopen=()=>{
      console.log("连接成功");
      send.disabled=false//修改发送按钮可用状态
    }
    ws.onmessage=(msg)=>{
      console.log(msg);
      msgId.innerHTML=msg.data
    }
    ws.onclose=()=>{
      console.log("关闭连接");
      send.disabled=true
    }
  }
  send.onclick=function(){
    console.log("开始发送");
    ws.send("hello i am demo.html")
  }
</script>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

4、在上面的基础上改造完善代码

将app.js里面关于websocket的代码提出到websocket_utils.js并导出

//4、websocket的使用
//引入websocket
const WebSocket=require('ws')
//4-1、创建对象,绑定端口
const wss=new WebSocket.Server({
  port:9998
});

//服务端开启了监听
//4-2、监听连接事件
module.exports.listen=()=>{
  wss.on('connection',(client)=>{
    console.log("客户端连接成功。。。");
    //4-3、监听接收消息事件
    client.on('message',(msg)=>{
      console.log("接收到来着客户端的信息:"+msg);
      //模拟客户端往服务端发送数据
      client.send("hello websocket!i am app.js")
    })
  })
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

在app.js里将websocket_utils.js导入并监听

//4、websocket的使用
//引入websocket_utils.js
const webSocketService=require('./utils/websocket_utils')
//开启服务端的监听
webSocketService.listen()
  • 1
  • 2
  • 3
  • 4
  • 5

2、springboot中使用websocket

案例一

1、引入依赖
<!--websocket-->
        <dependency>  
           <groupId>org.springframework.boot</groupId>  
           <artifactId>spring-boot-starter-websocket</artifactId>  
       </dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
2、添加配置类
package com.furenqiang.system.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

/**
 * 开启WebSocket支持
 * @author EricFRQ
 */
@Configuration
public class WebSocketConfig {

	@Bean  
    public ServerEndpointExporter serverEndpointExporter() {  
        return new ServerEndpointExporter();  
    }  
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
3、添加工具类
package com.furenqiang.system.utils;

import java.util.concurrent.atomic.AtomicInteger;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * 前后端交互的类实现消息的接收推送(自己发送给自己)
 * 
 * @ServerEndpoint(value = "/test/one") 前端通过此URI和后端交互,建立连接
 */
@ServerEndpoint(value = "/test/one")
@Component
public class WebSocketUtil {

    /** 记录当前在线连接数 */
    private static AtomicInteger onlineCount = new AtomicInteger(0);
    
    private static final Logger logger=LoggerFactory.getLogger(WebSocketUtil.class);

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session) {
        onlineCount.incrementAndGet(); // 在线数加1
        logger.info("有新连接加入:{},当前在线人数为:{}", session.getId(), onlineCount.get());
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(Session session) {
        onlineCount.decrementAndGet(); // 在线数减1
        logger.info("有一连接关闭:{},当前在线人数为:{}", session.getId(), onlineCount.get());
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message
     *            客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, Session session) {
    	logger.info("服务端收到客户端[{}]的消息:{}", session.getId(), message);
        this.sendMessage("Hello, " + message, session);
    }

    @OnError
    public void onError(Session session, Throwable error) {
    	logger.error("发生错误");
        error.printStackTrace();
    }

    /**
     * 服务端发送消息给客户端
     */
    private void sendMessage(String message, Session toSession) {
        try {
        	logger.info("服务端给客户端[{}]发送消息{}", toSession.getId(), message);
            toSession.getBasicRemote().sendText(message);
        } catch (Exception e) {
        	logger.error("服务端发送消息给客户端失败:{}", e);
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
4、新建前端测试页面

resources下新建static文件夹,static下新建index.html

<!DOCTYPE HTML>
<html>
<head>
<title>My WebSocket</title>
</head>

<body>
    <input id="text" type="text" />
    <button onclick="send()">Send</button>
    <button onclick="closeWebSocket()">Close</button>
    <div id="message"></div>
</body>

<script type="text/javascript">
    var websocket = null;

    //判断当前浏览器是否支持WebSocket, 主要此处要更换为自己的地址
    if ('WebSocket' in window) {
        websocket = new WebSocket("ws://localhost:10012/test/one");
    } else {
        alert('Not support websocket')
    }

    //连接发生错误的回调方法
    websocket.onerror = function() {
        setMessageInnerHTML("error");
    };

    //连接成功建立的回调方法
    websocket.onopen = function(event) {
        //setMessageInnerHTML("open");
    }

    //接收到消息的回调方法
    websocket.onmessage = function(event) {
        setMessageInnerHTML(event.data);
    }

    //连接关闭的回调方法
    websocket.onclose = function() {
        setMessageInnerHTML("close");
    }

    //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
    window.onbeforeunload = function() {
        websocket.close();
    }

    //将消息显示在网页上
    function setMessageInnerHTML(innerHTML) {
        document.getElementById('message').innerHTML += innerHTML + '<br/>';
    }

    //关闭连接
    function closeWebSocket() {
        websocket.close();
    }

    //发送消息
    function send() {
        var message = document.getElementById('text').value;
        websocket.send(message);
    }
</script>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
5、测试

访问地址http://localhost:10012/index.html
浏览器输入内容 点击发送send按钮
在这里插入图片描述
服务端
在这里插入图片描述

案例二

1、和上面一二步骤一样,引入依赖,添加配置类
2、添加工具类
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * 前后端交互的类实现消息的接收推送(自己发送给自己)
 * 
 * @ServerEndpoint(value = "/test/one") 前端通过此URI和后端交互,建立连接
 */
@ServerEndpoint(value = "/websocket/one")
@Component
public class WebSocketUtil {

	/** 记录当前在线连接数 */
	private static AtomicInteger onlineCount = new AtomicInteger(0);

	private static final Logger logger = LoggerFactory.getLogger(WebSocketUtil.class);

	/** 存放所有在线的客户端 */
	private static Map<String, Session> clients = new ConcurrentHashMap<>();

	/**
	 * 连接建立成功调用的方法
	 */
	@OnOpen
	public void onOpen(Session session) {
		onlineCount.incrementAndGet(); // 在线数加1
		clients.put(session.getId(), session);
		logger.info("有新连接加入:{},当前在线人数为:{}", session.getId(), onlineCount.get());
	}

	/**
	 * 连接关闭调用的方法
	 */
	@OnClose
	public void onClose(Session session) {
		onlineCount.decrementAndGet(); // 在线数减1
		clients.remove(session.getId());
		logger.info("有一连接关闭:{},当前在线人数为:{}", session.getId(), onlineCount.get());
	}

	/**
	 * 收到客户端消息后调用的方法
	 *
	 * @param message 客户端发送过来的消息
	 */
	@OnMessage
	public void onMessage(String message, Session session) {
		logger.info("服务端收到客户端[{}]的消息:{}", session.getId(), message);
		this.sendMessage(message, session);

	}

	@OnError
	public void onError(Session session, Throwable error) {
		logger.error("发生错误");
		error.printStackTrace();
	}

	/**
	 * 服务端发送消息给客户端
	 */
	public void sendMessage(String message, Session fromSession) {
		if (fromSession == null) {
			for (Map.Entry<String, Session> sessionEntry : clients.entrySet()) {
				fromSession = sessionEntry.getValue();
				logger.info("服务端给客户端[{}]发送消息{}", fromSession.getId(), message);
				fromSession.getAsyncRemote().sendText(message);
			}
		} else {
			for (Map.Entry<String, Session> sessionEntry : clients.entrySet()) {
				Session toSession = sessionEntry.getValue();
				// 排除掉自己
				if (!fromSession.getId().equals(toSession.getId())) {
					logger.info("服务端给客户端[{}]发送消息{}", toSession.getId(), message);
					toSession.getAsyncRemote().sendText(message);
				}
			}
		}

	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
3、使用
	WebSocketUtil webSocketUtil = new WebSocketUtil();
	//websocket推送给前端
	webSocketUtil.sendMessage(jobInfo.toString(), null);
  • 1
  • 2
  • 3

二、浏览器端:vue中使用websocket

1、ws协议连接,地址比如ws://localhost:9998

1、封装websocket到socket_service.js

导出一个类WebSocketService,实现如下几步:

  • 定义类并设计成单例模式
  • 定义连接方法connect
  • 连接方法connect里监听onxxx所有事件
  • 存储回调函数
  • 接收数据的处理
  • 定义发送数据的方法
  • 挂载类的实例对象到Vue的原型对象上
export default class WebSocketService{
  /*
  * 单例模式
  */
  static instance=null
  static get Instance(){
    if(!this.instance){
      this.instance= new WebSocketService()
    }
    return this.instance
  }

  ws=null
  //连接服务器的方法
  connect(){
    if(!window.WebSocket){
      return "您的浏览器不支持websocket"
    }
    this.ws=new WebSocket("ws://localhost:9998")
    this.ws.onopen=()=>{
      console.log("连接成功");
    }
    this.ws.onclose=()=>{
      console.log("关闭连接");
    }
    this.ws.onmessage=(msg)=>{
      console.log(msg);
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

2、在main.js中全局引用

在main.js里引入并调用

import WebSocketService from './utils/websocket_utils'
//websocket的连接并监听
WebSocketService.Instance.connect()
//websocket注册全局组件,可在其他页面使用this.$socket来获取到WebSocketService对象
Vue.prototype.$socket = WebSocketService.Instance
  • 1
  • 2
  • 3
  • 4
  • 5

此时启动项目后,就可自动连接

2、使用http协议连接比如http://localhost:8040

资源包:node写的websocket引擎使用http协议连接的
1、下载依赖:npm install vue-socket.io@3.0.7 --s
2、使用:main.js里面引入

import VueSocketIO from "vue-socket.io";
Vue.use(
  new VueSocketIO({
    debug: true,
    connection: "http://localhost:8040?userid=" + sessionStorage.getItem("inieToken"),
  }))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

3、使用页面中使用相应方法

<!-- 消息中心滚动消息 -->
<template>
  <div class="msgDivClass">
    <span class="msgSpanClass">{{ text }}</span>
  </div>
</template>

<script>
export default {
  data() {
    return {
      timerId: null,
      msg: "滚动1234567890开始1234567890过程1234567890结束1234567890",
      text: "",
      socket: null,
    };
  },
  components: {},
  computed: {},
  mounted() {
    this.connSocket();
    this.autoRoll();
  },
  created() {},
  methods: {
    connSocket() {
      this.sockets.subscribe("notification", (data) => {//notification为服务端发送的方法名
        data = JSON.parse(data);
        this.msg = data.content + ":" + data.description + "。";
        this.autoRoll();
      });
    },
    autoRoll() {
      let that = this;
      that.text = that.msg;
      this.timerId = setInterval(() => {
        that.text =
          that.text.substring(1, that.text.length) + that.text.substring(0, 1);
      }, 500);
    },
  },
  destroyed() {
    clearInterval(this.timerId);
    this.timerId = null;
  },
};
</script>
<style scoped>
.msgDivClass {
  width: 22%;
  height: 5%;
  border: 1px solid #809ca3;
  position: absolute;
  top: 3%;
  left: 0.5%;
}
.msgSpanClass {
  white-space: nowrap; /*强制span不换行*/
  display: inline-block; /*将span当做块级元素对待*/
  width: 100%; /*限制宽度*/
  overflow: hidden; /*超出宽度部分隐藏*/
  text-overflow: ellipsis; /*超出部分以点号代替*/
  margin-top: 9%;
  font-size: 25px;
  color: #ffffff;
}
</style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67

4、服务端代码如下:

var fs = require('fs');
var url = require("url");
var nicknames = {};
var app = require('http').createServer(function (request, response) {
    var pathname = url.parse(request.url).pathname;
    var responseJSON = {
        statusCode: 200, message: "", data: null
    };
    response.writeHead(200, {"Content-Type": "text/plain; charset=utf-8"});
    if (pathname == "/sendMsg")	//处理post方式请求
    {
        request.addListener("data", function (postdata) {
            var msgInfo = decodeURIComponent(postdata);
            var msgJSON = JSON.parse(msgInfo);
            var arruser = msgJSON.receiveId.split(",");

            var users = "";
			for (var item in nicknames) {
				for (var i=0;i<arruser.length;i++) {
					var userId = item.toString().split("_")[0];
					if (userId == arruser[i]) {
						msgJSON.receiveId = userId;
						nicknames[item].emit('notification', JSON.stringify(msgJSON));
						users += userId+",";
					}
				}
            }
			responseJSON.data = users;
        });
        request.addListener("end", function () {
            response.write(JSON.stringify(responseJSON));
            response.end();
        });
    } else if (pathname == "/getuserbyid") {
        var item = url.parse(request.url).query;
        if (nicknames[item]) {
            responseJSON.data = {
                userid: item,
                referer: nicknames[item].handshake.headers.referer,
                address: nicknames[item].handshake.address
            };
        } else {
            responseJSON.statusCode = 500;
            responseJSON.message = "用户不存在或未登录";
        }
        response.write(JSON.stringify(responseJSON));
        response.end();
    } else if (pathname == "/getuserlist") {
        var userlist = [];
        for (var item in nicknames) {
            userlist.push({
                userid: item,
                referer: nicknames[item].handshake.headers.referer,
                address: nicknames[item].handshake.address
            });
        }
        response.writeHead(200, {"Content-Type": "text/plain"});
        response.write(JSON.stringify(userlist));
        response.end();
    } else {
        response.writeHead(200, {"Content-Type": "text/plain"});
        //消息发送状态   0:成功   1:失败
        response.write("200");
        response.end();
    }
});
var io = require('socket.io').listen(app);
app.listen(8040);
io.sockets.on('connection', function (socket) {
    var query = socket.handshake.query;
    if (query.userid) {
        if (!nicknames[query.userid + "_" + query.t]) {
            nicknames[query.userid + "_" + query.t] = socket;
            console.log("登录:" + query.userid + "_" + query.t);
            console.log(socket.handshake.address);
            console.log(socket.handshake.headers.referer);
        }
    }
    //监听用户退出 
    socket.on('disconnect', function () {
        //将退出的用户从在线列表中删除 
        if (nicknames.hasOwnProperty(query.userid + "_" + query.t)) {
            //删除 
            delete nicknames[query.userid + "_" + query.t];
            console.log("退出:" + query.userid + "_" + query.t);
        }
    });
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88

三、其他项目中(我自己用的,可以不看)

1. 封装websocket的Api

/* eslint-disable no-mixed-spaces-and-tabs */
/*------------------------- web socket方法封装 -------------------------*/
    /*连接websocket*/
    var ws;
    var port = '0'; //前一次端口号,断线重连时用到
    var seq=0;//第几次请求握手
    export const websocketFun = (parmas) => {
        var WebSocketsExist = true;
	    try {
	        ws = new WebSocket("ws://" + parmas.websocketip + ":" + parmas.websocketport);
	    }
	    catch (ex) {
	        try {
	            ws = new WebSocket("ws://" + this.$store.state.websocketip + ":" + this.$store.state.websocketport);
	        }
	        catch (ex) {
	            WebSocketsExist = false;
	        }
	    }
	    if (!WebSocketsExist) {
	        return;
	    }
	    ws.onopen = WSonOpen;
	    //ws.onmessage = WSonMessage;
	    ws.onclose = WSonClose;
        ws.onerror = WSonError;
        return ws; 
      }

    function WSonOpen() {
        var json={};
		json.userid=sessionStorage.getItem("userId");
		json.username=sessionStorage.getItem("username");
        json.FSNo="01";
        json.svrtype="8";
        json.msgType="msg_HandShake";
        json.port=port;
        json.reportflag="1";
        json.format="0";
        json.seq=seq;
        seq++;
        let str = JSON.stringify(json);
        let length=str.length;
        let len=length.toString(16);
        len=len.padStart(4, "0"); 
        str=len+str;
        ws.send(str);
   }

function WSonClose() {
}

function WSonError() {
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

2. 使用(我自己的案例)

<template>
  <div class="meterSwitch">
    <div class="header">
      <div class="search">
        <el-form size="mini" :inline="true" :model="search" class="demo-form-inline">
          <el-form-item label="户号">
            <el-input v-model="search.customerNum"></el-input>
          </el-form-item>
          <el-form-item label="户名">
            <el-input v-model="search.customerName"></el-input>
          </el-form-item>
          <el-form-item label="电表地址">
            <el-input v-model="search.meterAddress"></el-input>
          </el-form-item>
          <el-form-item>
            <el-button icon="el-icon-search" size="mini" type="primary" @click="getMeterSwitchList">查询</el-button>
          </el-form-item>
        </el-form>
      </div>
      <div class="Newly">
        <el-button icon="el-icon-connection" size="mini" type="primary" @click="readingSelect">透抄</el-button>
      </div>
    </div>
    <div class="content">
      <el-table
        :data="tableData"
        border
        style="width: 100%"
        height="100%"
        ref="multipleTable"
        tooltip-effect="dark"
        @selection-change="handleSelectionChange"
      >
        <el-table-column align="center" type="selection" width="55"></el-table-column>
        <el-table-column
          align="center"
          :show-overflow-tooltip="true"
          width="150"
          label="电表ID"
          prop="fileId"
          v-if="false"
        ></el-table-column>
        <el-table-column
          align="center"
          :show-overflow-tooltip="true"
          width="150"
          label="集中器ID"
          prop="upGoingId"
          v-if="false"
        ></el-table-column>
        <!-- <el-table-column type="index" width="50" prop="index"></el-table-column> -->
        <el-table-column
          align="center"
          :show-overflow-tooltip="true"
          width="120"
          label="户名"
          prop="customerName"
        ></el-table-column>
        <el-table-column
          align="center"
          :show-overflow-tooltip="true"
          width="120"
          label="户号"
          prop="customerNum"
        ></el-table-column>
        <el-table-column
          align="center"
          :show-overflow-tooltip="true"
          width="150"
          label="电表地址"
          prop="meterAddress"
        ></el-table-column>
        <el-table-column
          align="center"
          :show-overflow-tooltip="true"
          label="安装地址"
          prop="installAddress"
        ></el-table-column>
        <el-table-column
          align="center"
          :show-overflow-tooltip="true"
          width="150"
          prop="readingStatus"
          label="透抄结果"
        >
          <template slot-scope="scope">
            <span v-if="scope.row.readingStatus==1" style="color: green">成功</span>
            <span v-else-if="scope.row.readingStatus==0" style="color: red">失败</span>
            <span v-else style="color: black">未透抄</span>
          </template>
        </el-table-column>
        <el-table-column
          align="center"
          :show-overflow-tooltip="true"
          width="150"
          label="数据内容"
          prop="readingData"
        ></el-table-column>
      </el-table>
    </div>
    <!-- 分页 -->
    <div class="block">
      <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="search.page"
        :page-sizes="pages"
        :page-size="search.size"
        layout="total,sizes, prev, pager, next, jumper"
        :total="params.total"
      ></el-pagination>
    </div>
  </div>
</template>

<script>
import { websocketFun } from "@/request/websocketApi";
import { getMeterSwitchList, openSwitch } from "@/request/meterapi";
export default {
  data() {
    return {
      ws: "",
      search: {
        page: 1,
        size: 10,
        meterAddress: "",
        customerName: "",
        customerNum: "",
        organizationid: "",
        gid: "",
        type:'',
      },
      // 分页
      pages: [10, 20, 40],
      tableData: [],
      exchangeTableData: [],
      params: {
        total: 0
      },
      dealRows: [],
      multipleSelection: []
    };
  },
  computed:{
    tree(){
      return this.$store.state.tree
    }
  },
  watch: {
    tree:{
      deep:true,//代表深层次的监听
      immediate:true,//页面初始化的时候就立即触发一次
      handler(val){
        // console.log('vuex树',val)
        if(val.type===3){
          this.search.meterAddress = val.name
        }else {
          this.search.meterAddress = ''
        }
        if(val.type===2){
          this.search.customerName = val.name
          this.search.gid = val.gid
          this.search.type = val.type
        }else {
          this.search.customerName = ''
        }
        if(val.type===1){
          this.search.gid = val.gid
          this.search.type = val.type
        }
        // console.log('this.search---',this.search)
        this.page = 1
        this.getMeterSwitchList();
      }
    }
  },
  methods: {
    getMeterSwitchList() {
      getMeterSwitchList(this.search).then(res => {
        this.tableData = res.data.data;
        this.params.total = res.data.total;
      });
      if (this.ws == "") {
        this.ws = websocketFun(this.$store.state);
        this.ws.onmessage = this.WSonMessage;
      }
    },
    WSonMessage(event) {
      if (!event) {
        return;
      }
      let str = event.data; //要截取的字符串
      let index = str.indexOf("{");
      let result = str.substr(index, str.length);
      let events = eval("(" + result + ")");
      if (events.result == "nak") {
        this.$message({
          message: "与前置机连接被拒绝!",
          type: "error",
          duration: 3000
        });
      } else if (events.result == "ack") {
        console.log("与前置机连接成功!");
      } else {
        console.log(events);
        if (events.errorCode == "ok") {
          this.$message({
            message: "操作成功!",
            type: "success",
            duration: 3000
          });
          //同时修改数据库里电表下达状态,关于电表的数据在events.objJson里,
          //还需解析,然后根据电表地址 判断index,将数据写入到对应的列
          // this.tableData[this.dealRow].readingStatus=1;
          // this.tableData[this.dealRow].readingData=events.objJson;
        } else if (events.errorCode == "notOnline") {
          this.$message({
            message: "操作失败,集中器不在线!",
            type: "error",
            duration: 3000
          });
          //同时修改数据库里电表下达状态,关于电表的数据在events.objJson里,
          //还需解析,然后根据电表地址 判断index,将数据写入到对应的行
          //events.objJson.forEach((val) => {
          this.multipleSelection.forEach(val => {
            this.tableData.forEach((v, i) => {
              if (val.fileId == v.fileId) {
                this.dealRows.push(i);
              }
            });
          });
          this.$refs.multipleTable.clearSelection();
          for (let dealRow of this.dealRows) {
            this.tableData[dealRow].readingStatus = 0;
            this.tableData[dealRow].readingData = events.objJson;
          }
          this.dealRows = [];
        } else if (events.errorCode == "failed") {
          this.$message({
            message: "操作失败!",
            type: "error",
            duration: 3000
          });
        } else {
          this.$message({
            message: events,
            type: "error",
            duration: 3000
          });
        }
      }
    },
    handleCurrentChange(val) {
      this.search.page = val;
      this.getMeterSwitchList();
    },
    handleSizeChange(val) {
      this.search.size = val;
      this.search.page = 1;
      this.getMeterSwitchList();
    },
    readingSelect() {
      if (this.multipleSelection.length == 0) {
        this.$message({
          message: "请勾选后操作!",
          type: "warning",
          duration: 2000
        });
      }
      if (this.ws.readyState == 1) {
        for (let select of this.multipleSelection) {
          let electricmeter = {};
          electricmeter.fileId = select.fileId;
          electricmeter.upGoingId = select.upGoingId;
          openSwitch(electricmeter).then(res => {
            let openSwitchStr = res.data.data;
            this.ws.send(openSwitchStr);
            console.log("已发送");
          });
        }
      } else {
        this.$message({
          message: "未连接前置机!",
          type: "warning",
          duration: 2000
        });
      }
      console.log(this.multipleSelection);
    },
    handleSelectionChange(val) {
      this.multipleSelection = val;
    }
  },
  created() {
    this.getMeterSwitchList();
  }
};
</script>

<style lang="scss">
.meterSwitch {
  height: 100%;
  .header {
    vertical-align: middle;
    .search {
      // display: inline-block;
      vertical-align: top;
    }
    .Newly {
      display: block;
    }
  }
  .content {
    height: calc(100% - 120px);
    margin-top: 10px;
    .el-form-item {
      width: 33% !important;
    }
    .demo-table-expand {
      font-size: 0;
    }
    .el-form-item__label {
      // width: 90px;
      color: #99a9bf !important;
    }
    .demo-table-expand .el-form-item {
      margin-right: 0;
      margin-bottom: 0;
      width: 50%;
    }
  }
}
</style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333

3. 使用vuex保存连接websocket的ip、端口等信息

1、安装vuex

import vuex from 'vuex'
  • 1

2、在main.js里把vuex注册到vue全局组件里

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import store from './store/index.js'
import Vuex from 'vuex'

Vue.use(ElementUI)
Vue.use(Vuex)//使用vuex
Vue.config.productionTip = false
import './assets/font/iconfont.css'
// 引入echarts
import echarts from 'echarts'
Vue.prototype.$echarts = echarts
// 引入reset.css
import './assets/css/reset.css'
import './assets/css/base.css'

state: {
    websocketip:"193.168.1.100",
    websocketport:"20020",
  },
var store = new vuex.Store({//创建vuex中的store对象
    state
})

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/964321
推荐阅读
相关标签
  

闽ICP备14008679号