websocket是一种通信协议,和http、tcp/ip协议是一样的,建立在浏览器和服务器之间的长链接应用;
首先要说到的就是在spring boot 框架上使用websocket功能,进行通信。发送消息与接收消息功能;
一、群发消息功能
1.群发消息,也就是一个发送方,发送消息,所有链接用户都能接收消息,如果要做离线消息处理的话,需要其他功能;
a.java 代码部分
核心类,与浏览器的websocket进行交互
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.springframework.stereotype.Component;
@ServerEndpoint(value = "/sendMessage")
@Component
public class MyWebSocket{
//静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
private static int onlineCount = 0;
//concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
private static CopyOnWriteArraySetwebSocketSet = new CopyOnWriteArraySet();
//与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session session;
@Autowired
private MessageService messageService;
/*** 连接建立成功调用的方法*/
@OnOpen
public void onOpen(Session session)
{
this.session = session;
webSocketSet.add(this); //加入set中
addOnlineCount(); //在线数加1
System.out.println("有新连接加入!当前在线人数为" + getOnlineCount());
try
{
sendMessage(CommonConstant.CURRENT_WANGING_NUMBER);
}
catch (IOException e)
{
System.out.println("IO异常");
}
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose()
{
webSocketSet.remove(this); //从set中删除
subOnlineCount(); //在线数减1
System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());
}
/**
* 收到客户端消息后调用的方法
*
* @param message 客户端发送过来的消息*/
@OnMessage
public void onMessage(String message, Session session)
{
System.out.println("来自客户端的消息:" + message);
//群发消息
for (MyWebSocket item : webSocketSet)
{
try
{
item.sendMessage(message);
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
/**
* 群发自定义消息
* */
public static void sendInfo(String message) throws IOException
{
for (MyWebSocket item : webSocketSet)
{
try
{
item.sendMessage(message);
}
catch (IOException e)
{
continue;
}
}
}
private void sendMessage(String message) throws IOException
{
System.out.println("hello");
}
public static synchronized int getOnlineCount()
{
return onlineCount;
}
public static synchronized void addOnlineCount()
{
MyWebSocket.onlineCount++;
}
public static synchronized void subOnlineCount()
{
MyWebSocket.onlineCount--;
}
}
上下文监听
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();
}
}
如果此时需要引入service接口,通过自动装载的方式注入接口,则需要加入一个类,以便于引用
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
@Component
@Lazy(false)
public class ApplicationContextRegister implements ApplicationContextAware
{
private static ApplicationContext APPLICATION_CONTEXT;
/**
* 设置spring上下文 * * @param applicationContext spring上下文 *
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException
{
APPLICATION_CONTEXT = applicationContext;
}
public static ApplicationContext getApplicationContext()
{
return APPLICATION_CONTEXT;
}
}
用法:
//webSocket不能使用自动装载方式,使用spring反射
ApplicationContext act = ApplicationContextRegister.getApplicationContext();
MessageService messagelogService = act.getBean(MessageService.class);
这样就能引用service中方法
b.前段代码部分
<!docment html>
<html>
<head>
<title>My WebSocket</title>
</head>
<body>
welcome<br/>
<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://10.200.9.165:8088/bales/websocket/90950");
}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 + ' '; }
//关闭连接
function closeWebSocket(){ websocket.close(); }
//发送消息
function send(){ var message = document.getElementById('text').value; websocket.send(message); }
</script>
</html>