//第一步: html js
//报价socket
function priceSocket(futureType) {
var params;
if (typeof (WebSocket) == "undefined") {
layer.msg("您的浏览器不支持WebSocket,请更换浏览器!");
} else {
params = {
'futureType': futureType,
};
//实现化WebSocket对象,指定要连接的服务器地址与端口,建立连接(如果配置了nginx 也需要相应的配置) socket = new WebSocket("ws://localhost:8080/websocket/socketServer");
socket = new WebSocket("ws://localhost:8080/websocket/server");
//打开事件
socket.onopen = function () {
// 发送查询报价参数
socket.send(JSON.stringify(params));
};
//获得消息事件
socket.onmessage = function (msg) {
var priceData = JSON.parse(msg.data).data;
//这里我的dome是返回一个 list
if (priceData && priceData.length>0) {
for (var i = 0; i < priceData.length; i++) {
loadTable(priceData,i);
}
};
};
//关闭事件
socket.onclose = function () {
console.log("Socket已关闭");
};
//发生了错误事件
socket.onerror = function () {
console.log("Socket发生了错误");
window.location.reload();
};
//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function(){
socket.close();
}
/**
* 加载每一行的数据(自己写的加载方法)
* @param priceData
* @param i
*/
var loadTable = function (priceData,i) {
let price = '';
var priceText='';
var defaultPrice="失效";
for(var j =4;j<13;j++){
switch (j) {
case 4:price= priceData[i].futureBasis1; break;
case 5:price= priceData[i].futureBasis2; break;
case 6:price= priceData[i].futureBasis3; break;
case 7:price= priceData[i].futureBasis4; break;
case 8:price= priceData[i].futureBasis5; break;
case 9:price= priceData[i].futureBasis6; break;
case 10:price= priceData[i].futureBasis7; break;
case 11:price= priceData[i].futureBasis8; break;
case 12:price= priceData[i].futureBasis9; break;
}
//将数据展示给前端
if(price){
$(".layui-table-box .layui-table tbody tr[data-index="+i+"] td[data-key=2-0-"+j+"] div").text(price);
}else{
$(".layui-table-box .layui-table tbody tr[data-index="+i+"] td[data-key=2-0-"+j+"] div").text(defaultPrice);
}
};
}
}
}
后台服务:
package com.dingjia.jiaxin.websocket;
import com.alibaba.fastjson.JSON;
import com.dingjia.jiaxin.entity.FuturePrice;
import com.dingjia.jiaxin.entity.ProductBasis;
import com.dingjia.jiaxin.service.ProductBasisService;
import com.dingjia.jiaxin.service.impl.ProductBasisServiceImpl;
import com.dingjia.jiaxin.vo.QuoteVo;
import com.dingjia.jiaxin.vo.Result;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;
/**
* @Author: yaode
* @Date: 2020/04/01
* @Description: websocketPC服务端
*/
@ServerEndpoint(value = "/websocket/server")
@Component
public class WebSocketFutureServer {
private final Logger log = LoggerFactory.getLogger(this.getClass());
public static ProductBasisService productBasisService;
/**
* concurrent包的线程安全Set,用来存放每个客户端对应的WebSocket对象
*/
private static CopyOnWriteArraySet<WebSocketFutureServer> webSocketSet = new CopyOnWriteArraySet<WebSocketFutureServer>();
/**
* 与某个客户端的连接会话,需要通过它来给客户端发送数据
*/
private Session session;
private boolean start = true;
private long sleep = 500;
private Thread th;
private ProductBasis productBasis;
/**
* 连接建立成功调用的方法
*/
@OnOpen
public void onOpen(Session session) {
this.session = session;
webSocketSet.add(this);
log.info("连接成功!");
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose() {
if (th != null && th.isAlive()) {
//th.stop();
th.interrupt();
}
webSocketSet.remove(this);
log.info("连接关闭!");
}
/**
* 收到客户端消息后调用的方法
*
* @param message 客户端发送过来的消息
*/
@OnMessage
public void onMessage(String message, Session session) throws Exception {
log.info("收到报价查询条件:" + message);
ObjectMapper objectMapper = new ObjectMapper();
productBasis = objectMapper.readValue(message, ProductBasis.class);
th = new Thread(new thread());
th.start();
}
/**
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error) {
if (th != null && th.isAlive()) {
th.interrupt();
}
log.error("发生错误");
error.printStackTrace();
}
/**
* 报价线程
*/
class thread extends Thread {
@Override
public void run() {
while (true) {
try {
if (start) {
for (WebSocketFutureServer item : webSocketSet) {
if (item.session == session) {
item.sendPrice(productBasis);
}
}
}
Thread.sleep(sleep);
} catch (Exception e) {
Thread.currentThread().interrupt();
}
}
}
}
/**
* 实现服务器主动推送
*/
public void sendMessage(Object message) {
try {
this.session.getBasicRemote().sendText(JSON.toJSONString(message));
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 实现服务器主动群发消息
*/
public static void sendInfo(Object message) {
for (WebSocketFutureServer item : webSocketSet) {
item.sendMessage(message);
}
}
/**
* 实现服务器主动推送报价信息
*/
public void sendPrice(ProductBasis productBasis) {
try {
//这里处理返回值。productBasis是我 前端传过来的一个属性,这里自动封装成对象
Result result = new Result();
List<Map<String,Object>> maps = WebSocketFutureServer.productBasisService.getFutureTypes(productBasis);
result.setData(maps);
this.session.getBasicRemote().sendText(JSON.toJSONString(result));
} catch (Exception e) {
e.printStackTrace();
}
}
public static CopyOnWriteArraySet<WebSocketFutureServer> getWebSocketSet() {
return webSocketSet;
}
public static void setWebSocketSet(CopyOnWriteArraySet<WebSocketFutureServer> webSocketSet) {
WebSocketFutureServer.webSocketSet = webSocketSet;
}
public Session getSession() {
return session;
}
public void setSession(Session session) {
this.session = session;
}
}
最后一步:开启websocket支持
package com.dingjia.jiaxin.config;
import com.dingjia.jiaxin.service.ProductBasisService;
import com.dingjia.jiaxin.websocket.WebSocketFutureServer;
import com.dingjia.jiaxin.websocket.WebSocketServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* FileName: WebSocketConfig
* @Author: yaode
* Description: 开启websocket支持
*/
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
@Autowired
public void setMessageService(ProductBasisService productBasisService){
WebSocketFutureServer.productBasisService = productBasisService;
}
}