Java+WebSocket 实现订单提示功能
首先socket API 定义好
package com.recruit.work.controller.socket;
import com.alibaba.fastjson.JSONObject;
import com.recruit.work.bean.AppMsg;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author 老肖
* @packge com.xbxkj.config.config
* @data 2019-06-11 12:00
* @project Metaphysics
*/
@ServerEndpoint(value = "/websocket/{userId}/{type}" )
@Component
public class MyWebSocket {
//静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
private static int onlineCount = 0;
//concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
private static ConcurrentHashMap<String,MyWebSocket> webSocketSet = new ConcurrentHashMap<String,MyWebSocket>();
//与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session session;
private String thisType;
//此处是解决无法注入的关键
private static ApplicationContext applicationContext;
//要注入的service或者dao
public static void setApplicationContext(ApplicationContext applicationContext) {
MyWebSocket.applicationContext = applicationContext;
}
/**
* 连接建立成功调用的方法*/
@OnOpen
public void onOpen(@PathParam(value = "userId") String param, @PathParam(value = "type") String type, Session session) {
this.session = session;
webSocketSet.put(param,this); //加入set中
thisType=type;
addOnlineCount(); //在线数加1
System.out.println("有新连接加入!当前在线人数为" + getOnlineCount());
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose() {
webSocketSet.remove(this); //从set中删除
subOnlineCount(); //在线数减1
System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());
}
/**
* 收到客户端消息后调用的方法
*
* @param message 客户端发送过来的消息*/
@OnMessage
public void onMessage(String message, Session session) throws IOException {
JSONObject jo = new JSONObject();
jo.put("message", message);
System.out.println("来自客户端的消息:" + jo.toString());
AppMsg appMsg= JSONObject.parseObject(jo.toString(), AppMsg.class);
sendInfo(jo.toString());
}
/**
* 发生错误时调用
*@OnError
**/
public void onError(Session session, Throwable error) {
System.out.println("发生错误");
error.printStackTrace();
}
public void sendMessage(String message) throws IOException {
try {
this.session.getBasicRemote().sendText(message);
System.out.println("发送出了新消息了");
}catch (Exception e){
webSocketSet.remove(this); //从set中删除
}
//this.session.getAsyncRemote().sendText(message);
}
/**
* 群发自定义消息
* */
public static void sendInfo(String message) throws IOException {
for (String key : webSocketSet.keySet()) {
try {
String type=webSocketSet.get(key).thisType;
//如果 循环到后台 那么发送提醒
if(type.equals("admin")){
JSONObject jo = new JSONObject();
jo.put("message", message);
System.out.println("有人注册了");
webSocketSet.get(key).sendMessage(jo.toString());
}
} catch (IOException e) {
continue;
}
}
}
/**
* 单发自定义消息
* userId 给谁发
* */
public static void sendToUser(String message,String userId) throws IOException {
for (String key : webSocketSet.keySet()) {
if(key.equals(userId)){
try {
webSocketSet.get(key).sendMessage(message);
} catch (IOException e) {
e.printStackTrace();
}
return;
}
}
}
public static synchronized int getOnlineCount() {
return onlineCount;
}
public static synchronized void addOnlineCount() {
MyWebSocket.onlineCount++;
}
public static synchronized void subOnlineCount() {
MyWebSocket.onlineCount--;
}
}
SpringBoot启动类 添加开启 WebSocket
//springboot2.0开启websocket支持
@Bean
public ServerEndpointExporter serverEndpointExporter() {
log.info("正在启动开启websocket支持") ;
return new ServerEndpointExporter();
}
开放权限 (具体更具自己 项目)
map.put("/websocket/**", "anon");
找到订单的借口调用API 确保有了订单在加上下面这个代码
try {
//通知所有人的方法
MyWebSocket.sendInfo("0");
System.out.println("有新的用户 ");
} catch (IOException e) {
e.printStackTrace();
}
Web 前端代码
//这个是标签
<audio src="${base}/aa.mp3" muted autoplay loop id="myaudio" style="display: none"></audio>
<script>
//注意上线后 改成服务器的 地址
var url = "ws://localhost:1488";
//判断当前浏览器是否支持WebSocket
if ('WebSocket' in window) {
websocket = new WebSocket(url+"/websocket/"+new Date().getTime()+"/admin");
}
else {
layer.msg("当前浏览器不支持的消息通道")
}
//连接发生错误的回调方法
websocket.onerror = function () {
layer.msg("消息通道发生错误")
};
//连接成功建立的回调方法
websocket.onopen = function (event) {
websocket.send("你好")
};
//接收到消息的回调方法
websocket.onmessage = function (event) {
// console.log("收到了消息!")
var msg = JSON.parse(event.data);
// alert(event.data)
console.log("data:"+event.data)
console.log(msg);
console.log(msg.message=="0");
if(msg.message=="0"){//有新订单
// console.log("执行提醒方法")
Win10.newMsg(new Date(),msg.message )
//谷歌浏览不支持 自动 播放 所以下面写了 run方法
run();
}
};
//连接关闭的回调方法
websocket.onclose = function () {
websocket = new WebSocket(url+"/websocket/"+new Date().getTime()+"/admin");
};
//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function () {
websocket.close();
}
//关闭连接
function closeWebSocket() {
websocket.close();
}
/*
* muted 静音
* autoplay 自动播放
* loop 循环播放
*/
var audio = document.getElementById('myaudio');
var t1 = 3e3;//如果是轮询,这个时间必须大于音频的长度。如果是webscoket,应该设置一个状态play,避免重复播放,如下:
var t2 = 2500;//音频的长度,确保能够完整的播放给用户
var play = false;
function run(){
if(play){
return false;
}
audio.currentTime = 0;//设置播放的音频的起始时间
audio.volume = 1;//设置音频的声音大小
audio.muted = false;//关闭静音状态
play = true;
setTimeout(function(){
play = false;
audio.muted = true;//播放完毕,开启静音状态
},t2);
}
</script>
如果这个代码对你有帮助 请对我有点点 小小的支持 让我更新下去!
版权声明:本文为weixin_45029961原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。