package com.huawei.e.itr.common.utils;
import lombok.extern.slf4j.Slf4j;
import java.util.HashMap;
import java.util.Map;
/**
* @author zhao pan
* @Date 10:27 2020/07/01
* @Description websocket项目发送消息
*/
@Slf4j
public class WebSocketSendMsgUtil {
private static String websocketBaseUrl = "http://e.itr.huawei.com/e/ws";
/**
*
* @param url 相对路径 重保(zb)
* @param params 参数 ids(发送的ID集合(set), mes消息)
*/
public static void sendMes(String url, Map<String, Object> params ){
//判断生产和测试
params.put("status", CommonUtil.isProductEnv() ? "2" : "1");
Map<String, String> header = null;
try {
header = new HashMap<>();
header.put("Accept", "application/json");
header.put("Content-Type", "application/json");
HttpUtilows.doPost(websocketBaseUrl + "/sendMes/" + url, null, header, params);
} catch (Exception e) {
e.printStackTrace();
log.error("消息发送失败", url, params.get("mes"));
}
}
}
location /e/websocket {
proxy_pass http://app_server;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 120s;
proxy_set_header Upgrade websocket;
proxy_set_header Connection Upgrade;
access_log logs/websocket.log;
}
package com.huawei.e.itr.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
/**
* websocket操作工具 , 重保使用ZB开头+工号
*/
@ServerEndpoint("/link/{userAgentId}")
@Component
public class WebSocketUtil {
static Logger log = LoggerFactory.getLogger(WebSocketUtil.class);
public static ConcurrentHashMap<String, Session> linkCustomers = new ConcurrentHashMap<>(); //连接的客户端
/**
* 连接建立成功调用的方法*/
@OnOpen
public void onOpen(Session session, @PathParam("userAgentId") String userAgentId) {
log.info("新连接" + userAgentId, userAgentId);
linkCustomers.put(userAgentId, session);
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose(@PathParam("userAgentId") String userAgentId) {
log.info("断开连接", userAgentId);
linkCustomers.remove("userAgentId");
}
/**
* 收到客户端消息后调用的方法
*
* @param message 客户端发送过来的消息*/
@OnMessage
public void onMessage(String message, Session session, @PathParam("userAgentId") String userAgentId) {
log.debug("收到" + userAgentId + "消息:" + message);
}
/**
* 连接失败
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error, @PathParam("userAgentId") String userAgentId) {
linkCustomers.remove(userAgentId);
error.printStackTrace();
}
/**
* 实现服务器主动推送
*/
public static void sendMessage(String message, List<String> userAgentIds) throws IOException {
for(String userAgentId : userAgentIds){
Session session = linkCustomers.get(userAgentId);
if(session != null && session.isOpen()){
log.info(userAgentId + " 发送消息:" + message);
session.getBasicRemote().sendText(message);
}
}
}
/**
* 群发自定义消息
* */
public static void sendInfo(String message,@PathParam("sid") String sid) throws IOException {
}
}
package com.huawei.e.itr.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* websocket配置文件
*/
@Configuration
public class WebsocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
package com.huawei.e.itr.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
/**
* @author zhao pan
* @Date 16:38 2020/7/2
* @Description
*/
@Configuration
public class CorsConfig {
@Bean
public CorsFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("*");
config.setAllowCredentials(true);
config.addAllowedMethod("*");
config.addAllowedHeader("*");
// config.addExposedHeader("*");
UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
configSource.registerCorsConfiguration("/**", config);
return new CorsFilter(configSource);
}
}
package com.huawei.e.itr.controller;
import com.huawei.e.itr.common.utils.Result;
import com.huawei.e.itr.config.TestWebSocketUtil;
import com.huawei.e.itr.config.WebSocketUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
/**
* @author zhao pan
* @Date 9:35 2019/12/27
* @Description 发送消息的API
*/
@RestController
@RequestMapping("/sendMes")
public class SendMesController {
static Logger log = LoggerFactory.getLogger(SendMesController.class);
/**
* 重保发送消息
*
* @param params ids 发送的ID集合, mes 发送的消息字符串, status 1测试环境 2生产环境
* @return
*/
@PostMapping(value = "/zb")
public Result zbSendMes(@RequestBody Map<String, Object> params)
{
try {
if (params.get("ids") == null || !(params.get("ids") instanceof List)) {
return Result.buildResult(Result.Status.BAD_REQUEST, "参数格式不准确");
}
List<String> ids = (List<String>) params.get("ids");
String mes = params.get("mes").toString();
String status = params.get("status").toString();
if(status.equals("1")){
TestWebSocketUtil.sendMessage(mes, ids);
}else {
WebSocketUtil.sendMessage(mes, ids);
}
} catch (Exception e) {
e.printStackTrace();
log.error("消息发送失败", e);
}
return Result.buildResult(Result.Status.OK);
}
}
//处理ws消息
websocketHandleMessage(msg){
this.$notify.success(msg);
this.queryWoListCount();
this.getToDoList(this.searchParam)
},
function sendMsg() {
//console.log(websocket);
setInterval(() => {
try {
console.log('状态',webSocket.readyState == 1 ? '已连接' : '其他状态')
if(webSocket.readyState == 1) {
webSocket.send('保持连接');
}
}catch (e) {
console.log(e)
}
},1000*20)
}
function createWebSocket(url,mycontext) {
if ('WebSocket' in window) {
webSocket = new WebSocket(url);
initWebSocket(mycontext,url);
sendMsg()
} else if ('MozWebSocket' in window) {
webSocket = new MozWebSocket(url);
initWebSocket(mycontext,url);
sendMsg()
} else {
console.log("Not support websocket");
}
}
function initWebSocket(mycontext,wsUrl) {
webSocket.onopen = function(event) {
console.log('链接成功',event);
connentFlag=true;
window.testTimer = 5000
}
webSocket.onmessage = function(event) {
if(event.data!=null && event.data!=='') {
console.log(event.data)
mycontext.websocketHandleMessage(event.data) //处理消息
}
}
webSocket.onclose = function(e) {
console.log('链接关闭',e);
//webSocket.close();
connentFlag=false;
console.log(window.testTimer,mycontext.timerTimes)
if(mycontext.timerTimes <= 1000*15) {
mycontext.timer = setTimeout(() => {
createWebSocket(wsUrl,mycontext);
clearTimeout(mycontext.timer)
mycontext.timerTimes+=mycontext.timerTimes
},mycontext.timerTimes)
}
}
webSocket.onerror = function(e) {
console.log('连接错误',e);
//webSocket.close();
connentFlag=false;
console.log(window.testTimer,mycontext.timerTimes)
if(mycontext.timerTimes <= 1000*15) {
mycontext.timer = setTimeout(() => {
createWebSocket(wsUrl,mycontext);
clearTimeout(mycontext.timer)
mycontext.timerTimes+=mycontext.timerTimes
},mycontext.timerTimes)
}
}
}
const myNotification = (mycontext) => {
mycontext.$http.get(`../sys/common/getZbWsUrl`).then(res => {
console.log(res.data)
// "ws://e.itr.huawei.com/e/ws/link/"
if(res.status ==200){
let urls = res.data.data.url + 'wo' + res.data.data.id
console.log('urls',urls)
var connentFlag=false;
var webSocket = null;
try {
createWebSocket(urls,mycontext);
}catch (e) {
console.log(e)
}
}
})
}