创建一个springboot项目
导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<artifactId>spring-boot-starter-logging</artifactId>
<groupId>org.springframework.boot</groupId>
</dependency>
<dependency>
<!-- fastjson -->
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
配置config
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
自己发送自己
@ServerEndpoint(value = "/test/one")
@Component
public class OneWebSocket {
public static final Logger log =
(Logger) LoggerFactory.getLogger(OneWebSocket.class);
/**
* 记录当前在线连接数
*/
private static AtomicInteger onlineCount = new AtomicInteger(0);
/**
* 连接建立成功调用的方法
*/
@OnOpen
public void onOpen(Session session) {
onlineCount.incrementAndGet(); // 在线数加1
log.info("有新连接加入:{},当前在线人数为:{}", session.getId(), onlineCount.get());
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose(Session session) {
onlineCount.decrementAndGet(); // 在线数减1
log.info("有一连接关闭:{},当前在线人数为:{}", session.getId(), onlineCount.get());
}
/**
* 收到客户端消息后调用的方法
*
* @param message 客户端发送过来的消息
*/
@OnMessage
public void onMessage(String message, Session session) {
log.info("服务端收到客户端[{}]的消息:{}", session.getId(), message);
this.sendMessage("你收到一个自己发送的消息, " + message, session);
}
@OnError
public void onError(Session session, Throwable error) {
log.error("发生错误");
error.printStackTrace();
}
/**
* 服务端发送消息给客户端
*/
private void sendMessage(String message, Session toSession) {
try {
log.info("服务端给客户端[{}]发送消息{}", toSession.getId(), message);
toSession.getBasicRemote().sendText(message);
} catch (Exception e) {
log.error("服务端发送消息给客户端失败:{}", e);
}
}
}
自己发送给除自己以外的
@ServerEndpoint(value = "/test/oneToMany",configurator= GetHttpSessionConfigurator.class)
@Component
public class OneToManyWebSocket {
public static final Logger log =
(Logger) LoggerFactory.getLogger(OneWebSocket.class);
/** 记录当前在线连接数 */
private static AtomicInteger onlineCount = new AtomicInteger(0);
/** 存放所有在线的客户端 */
private static Map<String, Session> clients = new ConcurrentHashMap<>();
private HttpSession httpSession;
/**
* 连接建立成功调用的方法
*/
@OnOpen
public void onOpen(Session session,EndpointConfig config) {
onlineCount.incrementAndGet(); // 在线数加1
clients.put(session.getId(), session);
System.out.println("成功建立连接");
try {
httpSession =(HttpSession) config.getUserProperties().get(HttpSession.class.getName());
Integer userId = (Integer) httpSession.getAttribute("userId");
System.out.println(userId);
log.info("有新连接加入:{},当前在线人数为:{}", session.getId(), onlineCount.get());
} catch (Exception e) {
log.info("没有获取到用户");
}
// Integer userId =getClientId((WebSocketSession) session);
// System.out.println(userId);
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose(Session session) {
onlineCount.decrementAndGet(); // 在线数减1
clients.remove(session.getId());
log.info("有一连接关闭:{},当前在线人数为:{}", session.getId(), onlineCount.get());
}
/**
* 收到客户端消息后调用的方法
*
* @param message
* 客户端发送过来的消息
*/
@OnMessage
public void onMessage(String message, Session session) {
log.info("服务端收到客户端[{}]的消息:{}", session.getId(), message);
this.sendMessage(message, session);
}
@OnError
public void onError(Session session, Throwable error) {
log.error("发生错误");
error.printStackTrace();
}
/**
* 群发消息
*
* @param message
* 消息内容
*/
private void sendMessage(String message, Session fromSession) {
for (Map.Entry<String, Session> sessionEntry : clients.entrySet()) {
Session toSession = sessionEntry.getValue();
// 排除掉自己
if (!fromSession.getId().equals(toSession.getId())) {
log.info("服务端给客户端[{}]发送消息{}", toSession.getId(), message);
toSession.getAsyncRemote().sendText(message);
}
}
}
/**
* 获取用户标识
*/
private Integer getClientId(WebSocketSession session){
Integer clientId = (Integer) session.getAttributes().get("userId");
return clientId;
}
}
配置可以使用httpsession的
public class GetHttpSessionConfigurator extends ServerEndpointConfig.Configurator {
@Override
public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
HttpSession httpSession = (HttpSession) request.getHttpSession();
sec.getUserProperties().put(HttpSession.class.getName(), httpSession);
}
}
将所有request请求都携带上httpSession
@WebListener
public class RequestListener implements ServletRequestListener {
public void requestInitialized(ServletRequestEvent sre) {
//将所有request请求都携带上httpSession
((HttpServletRequest) sre.getServletRequest()).getSession();
}
public RequestListener() {
// TODO Auto-generated constructor stub
}
public void requestDestroyed(ServletRequestEvent arg0) {
// TODO Auto-generated method stub
}
}
配置controller
@RequestMapping("/login/{userId}")
public String login(HttpSession session, @PathVariable("userId") Integer userId){
if (session.getAttribute("userId")!=null){
session.removeAttribute("userId");
}
System.out.println("登录了"+userId);
session.setAttribute("userId",userId);
return "success";
}
这样websocket配置完毕
前端配置