准备
导入依赖
compile group: 'org.springframework', name: 'spring-messaging', version: '4.3.3.RELEASE'
compile group: 'org.springframework', name: 'spring-websocket', version: '4.3.3.RELEASE'
方式一
其中,path对应的路径就是前段通过ws协议调的接口路径
创建握手接口(拦截器)
public class HandshakeInterceptor extends HttpSessionHandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
Map attributes) throws Exception {
HttpServletRequest servletRequest = ((ServletServerHttpRequest) request).getServletRequest();
HttpSession session = servletRequest.getSession(false);
User user = (User) session.getAttribute("token");
if(user!=null){
attributes.put("token", user);
}
return super.beforeHandshake(request, response, wsHandler, attributes);
}
@Override
public void afterHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
Exception ex) {
super.afterHandshake(request, response, wsHandler, ex);
}
}
创建处理类
@Component
public class WebsocketEndPoint extends TextWebSocketHandler {
@Autowired
IProjectDeliverService iProjectDeliverService;
@Autowired
IProjectDeliverReplyService iProjectDeliverReplyService;
@Autowired
private IUserService iUserService;
/**
* 所有的用户
*/
private static final Map users ;
static{
users = new HashMap<>();
}
@Override
protected void handleTextMessage(WebSocketSession session,
TextMessage message) throws Exception {
super.handleTextMessage(session, message);
session.sendMessage(message);
}
@Override
public void afterConnectionEstablished(final WebSocketSession session) throws Exception {
User user = (User) session.getAttributes().get("token");
if(user != null)
users.put(user.getId() , session);
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
User user = (User) session.getAttributes().get("token");
// 如果用户对象还存在内存中,那么不进行退出记录
if(user != null){
iUserService.exit(DateUtils.dateToString(new Date()),user.getId());
System.out.println(user.getNickName()+" exits from the system ! Connection Closed!");
}
}
/**
* 发送给指定用户
* @param userIds 用户编号数组,不传(长度=0) 默认发送给所有用户
* @param message 消息内容
*/
public static void sendToUser( TextMessage message , List userIds){
try {
// 如果没有传用户编号 , 默认发送给所有用户
if(userIds == null || userIds.size() == 0){
if(users.keySet() != null && users.keySet().size() > 0 ){
for (Integer key : users.keySet()) {
if(users.get(key).isOpen())
users.get(key).sendMessage(message);
}
}
}else{ // 发送给指定的用户
for (Integer id : userIds) {
if(users.containsKey(id) && users.get(id).isOpen()){
users.get(id).sendMessage(message);
}
}
}
}catch (IOException e){
e.printStackTrace();
}
}
}
用户页面连接(sockjs-0.3.min.js自行下载)
后台调用sendToUser给指定用户发送信息
.................................................................................................
方式二
websocket入口
@Configuration
@EnableWebMvc
@EnableWebSocket
public class WebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
//setAllowedOrigins("*") 解决跨域问题
registry.addHandler(systemWebSocketHandler(),"/webSocketServer").addInterceptors(new WebSocketHandshakeInterceptor()).setAllowedOrigins("*");
registry.addHandler(systemWebSocketHandler(), "/sockjs/webSocketServer").addInterceptors(new WebSocketHandshakeInterceptor()).withSockJS();
}
@Bean
public WebSocketHandler systemWebSocketHandler(){
return new SystemWebSocketHandler();
}
}
拦截器,beforeHandshake在调用handler前处理方法。常用在注册用户信息,绑定WebSocketSession,在handler里根据用户信息获取WebSocketSession发送消息。
public class WebSocketHandshakeInterceptor implements HandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map attributes) throws Exception {
if (request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
HttpSession session = servletRequest.getServletRequest().getSession(false);
if (session != null) {
//使用userName区分WebSocketHandler,以便定向发送消息
attributes.put("userId",session.getAttribute("userId"));
}
}
return true;
}
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {
}
}
handle处理器
public class SystemWebSocketHandler implements WebSocketHandler {
private static final Map users;
static {
users = new HashMap<>();
}
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
String userId = (String) session.getAttributes().get("userId");
if(userId !=null){
users.put(userId,session);
}
session.sendMessage(new TextMessage("hello world"));
System.out.println("建立连接");
}
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage> message) throws Exception {
}
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
System.out.println("连接被关闭");
for (Map.Entry entry : users.entrySet()) {
if(entry.getValue().equals(session)){
users.remove(entry.getKey());
}
}
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
System.out.println("连接被关闭");
users.remove(session);
}
@Override
public boolean supportsPartialMessages() {
return false;
}
/**
* 给某个用户发送消息
*
* @param userId
* @param message
*/
public static void sendMessageToUser(String userId, TextMessage message) throws IOException {
Set> entries = users.entrySet();
for (Map.Entry entry : entries) {
if(entry.getKey().equals(userId))
entry.getValue().sendMessage(message);
}
}
}
用户建立socket连接(sockjs-0.3.min.js自行下载)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path;
String url = request.getServerName()+":"+request.getServerPort()+path;
%>
index
消息通知:
调用 sendMessageToUser推送信息
/**
* 消息推送
* @param msg 消息内容
* @param userId 推送用户id
*/
@RequestMapping(value = "pushMsg",method = RequestMethod.POST)
@ResponseBody
public String pushMsg(String userId, String msg) {
System.out.println("用户id:"+userId+" 推送的消息:"+msg);
try {
SystemWebSocketHandler.sendMessageToUser(userId,new TextMessage(msg));
return new Gson().toJson("success");
} catch (Exception e) {
System.out.println(e.getMessage()+"................");
e.printStackTrace();
return new Gson().toJson("fail:"+e);
}
}
相关链接
http://www.bridgeli.cn/archives/262
https://my.oschina.net/ldl123292/blog/304360
http://www.cnblogs.com/nosqlcoco/p/5860730.html