一、后端
1、安装websocket依赖

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>

2、配置websocket配置类

package com.iot.zmtestboot.websocketconfig;

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

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

3、配置websocket服务类

package com.sinoma.tj.realTimeMonitor.websocket;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicInteger;

@ServerEndpoint("/ws")
@Service
public class WebSocketServer {
	private static Logger log = LoggerFactory.getLogger(WebSocketServer.class);
	private static final AtomicInteger OnlineCount = new AtomicInteger(0);
	// concurrent包的线程安全Set,用来存放每个客户端对应的Session对象。
	private static CopyOnWriteArraySet<Session> SessionSet = new CopyOnWriteArraySet<Session>();



	/**
	 * 连接建立成功调用的方法
	 */
	@OnOpen
	public void onOpen(Session session) {
		SessionSet.add(session);
		int cnt = OnlineCount.incrementAndGet(); // 在线数加1
		log.info("有连接加入,当前连接数为:{}", cnt);
		//SendMessage(session, "收到消息,消息内容:");
	}

	/**
	 * 连接关闭调用的方法
	 */
	@OnClose
	public void onClose(Session session) {
		SessionSet.remove(session);
		int cnt = OnlineCount.decrementAndGet();
		log.info("有连接关闭,当前连接数为:{}", cnt);
	}

	/**
	 * 收到客户端消息后调用的方法
	 *
	 * @param message
	 *            客户端发送过来的消息
	 */
	@OnMessage
	public void onMessage(String message, Session session) {
		log.info("来自客户端的消息:{}",message);
		SendMessage(session, "收到消息,消息内容:"+message);
	}

	/**
	 * 出现错误
	 * @param session
	 * @param error
	 */
	@OnError
	public void onError(Session session, Throwable error) {
		log.error("发生错误:{},Session ID: {}",error.getMessage(),session.getId());
		error.printStackTrace();
	}

	/**
	 * 发送消息,实践表明,每次浏览器刷新,session会发生变化。
	 * @param session
	 * @param message
	 */
	public static void SendMessage(Session session, String message) {
		try {
			while (session.isOpen()){
				Date d = new Date();
				SimpleDateFormat sbf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				session.getBasicRemote().sendText(sbf.format(d));
				System.out.println("发送数据");
				System.out.println(sbf.format(d));
				Thread.sleep(1000);
			}
		} catch (IOException e) {
			log.error("发送消息出错:{}", e.getMessage());
			e.printStackTrace();
		}catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 群发消息
	 * @param message
	 * @throws IOException
	 */
//	public static void BroadCastInfo(String message) throws IOException {
//		for (Session session : SessionSet) {
//			if(session.isOpen()){
//				SendMessage(session, message);
//			}
//		}
//	}

	/**
	 * 指定Session发送消息
	 * @param sessionId
	 * @param message
	 * @throws IOException
	 */
//	public static void SendMessage(String message,String sessionId) throws IOException {
//		Session session = null;
//		for (Session s : SessionSet) {
//			if(s.getId().equals(sessionId)){
//				session = s;
//				break;
//			}
//		}
//		if(session!=null){
//			SendMessage(session, message);
//		}
//		else{
//			log.warn("没有找到你指定ID的会话:{}",sessionId);
//		}
//	}
}


4、如果启动报错javax.websocket.server.ServerContainer not available ,则修改依赖

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

二、前端部分

<template>
  <div>
    测试websocket<br />
    {{ recevieData }}
    <input type="button" value="打开socket" @click="initWebSocket" />
    <input type="button" value="关闭socket" @click="closewebsocket" />
    <!-- <input type="button" value="发送数据给java" @click="sendwebsocket" /> -->
  </div>
</template>

<script>
export default {
  name: "Home",
  data() {
    return {
      websock: null,
      recevieData: "",
    };
  },
  // created() {
  //   this.initWebSocket();
  // },
  destroyed() {
    // this.websocketsend("closeWebsocket");
    this.websock.close(); //离开路由之后断开websocket连接
  },
  methods: {
    // sendwebsocket() {
    //   //发送消息
    //   this.websocketsend("我是前端");
    // },
    closewebsocket() {
      this.websock.close(); //离开路由之后断开websocket连接
    },
    initWebSocket() {
      //初始化weosocket
      const wsuri = "ws://localhost:3310/ws";
      this.websock = new WebSocket(wsuri);
      this.websock.onmessage = this.websocketonmessage;
      this.websock.onopen = this.websocketonopen;
      this.websock.onerror = this.websocketonerror;
      this.websock.onclose = this.websocketclose;
    },
    websocketonopen() {
      //连接建立之后执行send方法发送数据
      let sendDataString = "连接数据";
      this.websocketsend(sendDataString);
    },
    websocketonerror() {
      //连接建立失败重连
      //this.initWebSocket();
    },
    websocketonmessage(e) {
      //数据接收
      console.log("数据接收");
      console.log(e.data);
      this.recevieData = e.data;
    },
    websocketsend(Data) {
      //数据发送
      this.websock.send(Data);
    },
    websocketclose(e) {
      //关闭
      console.log("断开连接", e);
    },
  },
};
</script>

三、如果导入pom依赖有问题,则选择自动适配

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
            <version>2.0.2.RELEASE</version>
        </dependency>

四、前后端互相通信
1、后端代码

package com.iot.zmtestboot.websocketconfig;

import org.springframework.stereotype.Service;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.CopyOnWriteArraySet;

@ServerEndpoint("/ws")
@Service
public class WebSocketServer {
    private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<>();
    // 与某个客户端的连接会话,需要通过它来给客户端发送数据
    private Session session;

    /**
     * 连接建立成功调用的方法*/
    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
        webSocketSet.add(this);     // 加入set中
        System.out.println("连接成功");
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        webSocketSet.remove(this);  // 从set中删除
        System.out.println("关闭连接");
    }

    @OnMessage
    public void onMessage(String message,Session session) {
        System.out.println("来自客户端的消息:" + message);
//        System.out.println(session.isOpen());
//        System.out.println(session);
        // 群发消息
        //while (session.isOpen()){
//            System.out.println(this.session);
            for (WebSocketServer item : webSocketSet) {
                try {
                    Date d = new Date();
                    SimpleDateFormat sbf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    //System.out.println(sbf.format(d));
                    item.sendMessage(sbf.format(d));
                    Thread.sleep(1000);

                } catch (IOException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
      // }

    }

    /**
     * 发生错误时调用
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        System.out.println("发生错误");
        error.printStackTrace();
    }

    /**
     * 发送消息
     * @param message 客户端消息
     * @throws IOException
     */
    private void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }
}

2、前端代码

<template>
  <div>
    测试websocket<br />
    {{ recevieData }}
    <input type="button" value="打开socket" @click="initWebSocket" />
    <input type="button" value="关闭socket" @click="closewebsocket" />
    <!-- <input type="button" value="发送数据给java" @click="sendwebsocket" /> -->
  </div>
</template>

<script>
export default {
  name: "Home",
  data() {
    return {
      websock: null,
      recevieData: "",
    };
  },
  // created() {
  //   this.initWebSocket();
  // },
  destroyed() {
    this.websock.close(); //离开路由之后断开websocket连接
  },
  methods: {
    closewebsocket() {
      this.websock.close();
    },
    initWebSocket() {
      //初始化weosocket
      const wsuri = "ws://localhost:3310/ws";
      this.websock = new WebSocket(wsuri);
      this.websock.onmessage = this.websocketonmessage;
      this.websock.onopen = this.websocketonopen;
      this.websock.onerror = this.websocketonerror;
      this.websock.onclose = this.websocketclose;
    },
    websocketonopen() {
      //连接建立之后执行send方法发送数据
      this.websocketsend("connectSuccess");
    },
    websocketonerror() {
      //连接建立失败重连
      //this.initWebSocket();
      // handleErrors(e)
    },
    websocketonmessage(e) {
      //数据接收
      console.log("数据接收");
      console.log(e.data);
      this.recevieData = e.data;
      this.websocketsend("OK");
    },
    websocketsend(Data) {
      //数据发送
      this.websock.send(Data);
    },
    websocketclose(e) {
      //关闭
      console.log("断开连接", e);
      // this.websocketonerror();
    },
  },
};
</script>

Logo

前往低代码交流专区

更多推荐