實現以下功能:
1、各個客戶端之間的消息互發;
2、客戶端向後臺發送消息;
3、後臺向客戶端發送消息
注:完整源代碼下載地址 http://download.csdn.net/detail/u010994277/9705588
代碼如下:
1)、配置處理器
/**
* WebScoket配置處理器
*
* @author www
* @Date 2016年12月8日
*/
@Component
@EnableWebSocket
@Configuration
@EnableWebMvc
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new MyWebSocketHandler(), "/portfolio2")// 添加一個處理器還有定義處理器的處理路徑
.addInterceptors(new MyHandShakeInterceptor());
registry.addHandler(new MyWebSocketHandler(), "/sockjs/portfolio2")// 添加一個處理器還有定義處理器的處理路徑
.addInterceptors(new MyHandShakeInterceptor()).withSockJS();
}
}
2、配置攔截器
/**
* Socket建立連接(握手)和斷開
*
* @author www
* @Date 2016年12月8日
*/
public class MyHandShakeInterceptor implements HandshakeInterceptor {
/**
* 握手之前,若返回false,則不建立鏈接
*/
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
Map<String, Object> attributes) throws Exception {
// TODO Auto-generated method stub
System.out.println("beforeHandshake-->");
if (request instanceof ServletServerHttpRequest) {
try {
ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
HttpSession session = servletRequest.getServletRequest().getSession(false);
if (session != null) {
String userId = (String) session.getAttribute(Constant.SESSION_USER_ID);
if(userId==null||userId.equals("")){
throw new Exception("用戶ID爲空");
}
attributes.put(Constant.SESSION_USER_ID,userId);
}else{
throw new Exception("session爲空");
}
} catch (Exception e) {
attributes.put(Constant.SESSION_USER_ID,"test-user");
}
}
return true;
}
/**
* 握手之後
*/
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
Exception exception) {
// TODO Auto-generated method stub
System.out.println("afterHandshake-->");
}
3、socket處理器
/**
* Socket處理器
*
* @author www
* @Date 2016年12月8日
*/
@Component
public class MyWebSocketHandler implements WebSocketHandler {
public static final Map<String, WebSocketSession> userSocketSessionMap;
static {
userSocketSessionMap = new HashMap<String, WebSocketSession>();
}
/**
* webscoket建立好鏈接之後的處理函數
*
* @param session
* 當前websocket的會話id,打開一個websocket通過都會生成唯一的一個會話,
* 可以通過該id進行發送消息到瀏覽器客戶端
*/
@Override
public void afterConnectionEstablished(WebSocketSession session)
throws Exception {
// TODO Auto-generated method stub
String uid = (String) session.getAttributes().get(Constant.SESSION_USER_ID);
System.out.println("用戶ID:" + uid + ";已建立連接");
// 每個鏈接來的客戶端都把WebSocketSession保存進來
if (userSocketSessionMap.get(uid) == null) {
userSocketSessionMap.put(uid, session);
}else{
userSocketSessionMap.remove(uid);
userSocketSessionMap.put(uid, session);
}
}
/**
* 客戶端發送服務器的消息時,的處理函數,在這裏收到消息之後可以分發消息
*/
@Override
public void handleMessage(WebSocketSession session,
WebSocketMessage<?> message) throws Exception {
// TODO Auto-generated method stub
Iterator<Map.Entry<String, WebSocketSession>> entries = userSocketSessionMap.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry<String, WebSocketSession> entry = entries.next();
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
if(entry.getKey().equals(session.getAttributes().get("userId"))){
String msg = "後臺已收到信息[" + message.getPayload().toString()+ "];用戶ID爲:" + entry.getKey();
System.out.println(msg);
message = new TextMessage(msg);
entry.getValue().sendMessage(message);
}
}
}
/**
* 消息傳輸過程中出現的異常處理函數
*/
@Override
public void handleTransportError(WebSocketSession session,
Throwable exception) throws Exception {
// TODO Auto-generated method stub
String userId=(String) session.getAttributes().get("userId");
userSocketSessionMap.remove(userId);
}
/**
* websocket鏈接關閉的回調
*/
@Override
public void afterConnectionClosed(WebSocketSession session,
CloseStatus closeStatus) throws Exception {
// TODO Auto-generated method stub
String userId=(String) session.getAttributes().get("userId");
userSocketSessionMap.remove(userId);
}
/**
* 是否支持處理拆分消息,返回true返回拆分消息
*/
@Override
public boolean supportsPartialMessages() {
// TODO Auto-generated method stub
return false;
}
/**
* 給所有在線用戶發送消息
*
* @param message
* @throws IOException
*/
public void broadcast(final String msg) throws IOException {
final TextMessage message=new TextMessage(msg);
Iterator<Entry<String, WebSocketSession>> it = userSocketSessionMap.entrySet().iterator();
// 多線程羣發
while (it.hasNext()) {
final Entry<String, WebSocketSession> entry = it.next();
if (entry.getValue().isOpen()) {
// entry.getValue().sendMessage(message);
new Thread(new Runnable() {
public void run() {
try {
if (entry.getValue().isOpen()) {
entry.getValue().sendMessage(message);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
}
}
/**
* 給某個用戶發送消息
*
* @param userName
* @param message
* @throws IOException
*/
public void sendMessageToUser(String uid, String msg)
throws IOException {
TextMessage message=new TextMessage(msg);
WebSocketSession session = userSocketSessionMap.get(uid);
if (session != null && session.isOpen()) {
session.sendMessage(message);
}
}