java websocket后台
WebSocket在网上的例子也不少,学习的时候也可以参照其他博文。重复的部分就不再强调了,直接上代码。
WebSocketServer.java这个文件就是websocket的后台监听系统,前端向后台发送数据的时候通过ip:port + /mychat这个地址来进行交互。
// WebSocketServer.java
package com.xxx.websocket;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import com.xxx.model.ChatInfo;
import com.xxx.service.ChatInfoService;
import com.xxx.model.WebSocketMessageBody;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ServerEndpoint(value="/mychat")
@Component
public class WebSocketServer {
private static final Logger logger = LoggerFactory.getLogger(WebSocketServer.class);
public static ConcurrentHashMap<Integer,WebSocketServer> webSocketSet = new ConcurrentHashMap<>();
private Session session;
private Integer id;
private String name;
//保存消息用
public static ChatInfoService service;
@OnOpen
public void onOpen(Session session) {
System.out.println("进入websocket_onOpen()");
this.session = session;
Map<String, List<String>> params = session.getRequestParameterMap();
try {
if(params==null||!params.containsKey("token")){
//认证失败,不能建立连接
session.close();
return;
}
/*验证是否登录*/
if(['这里业务自己来补充']){
try{
logger.debug("用户未登录,不能连接到websocket服务器!");
session.close();
}catch (Exception e){
//关闭出错可以忽略
}
return;
}
/*根据业务需要,也可以比对数据库信息来获取name和id*/
this.name = session.user.name;
this.id = session.user.id;
if(webSocketSet.containsKey(this.id )){
webSocketSet.get(this.id).close();
webSocketSet.remove(this.id);
}
webSocketSet.put(this.id,this);
logger.debug("有新连接加入" + this.id);
//sendMessage("连接成功");
} catch (Exception e) {
e.printStackTrace();
logger.error("websocket连接加入出错了,错误信息:",e);
}
}
@OnClose
public void onClose() {
logger.debug("连接关闭");
if(this.id!=null){
webSocketSet.remove(this.id);
}
}
@OnMessage
public void onMessage(String message,Session session) {
logger.debug("来自客户端消息:"+message);
//收到消息之后先记录消息到数据库
WebSocketMessageBody<ChatInfo> body = new WebSocketMessageBody();
ObjectMapper mapper = new ObjectMapper();
try {
body = (WebSocketMessageBody<ChatInfo>)mapper.readValue(message, body.getClass());
ChatInfo chatInfo = mapper.readValue(mapper.writeValueAsString(body.getData()),ChatInfo.class);
//设定发送者的姓名
chatInfo.setSendName(this.getName());
chatInfo.setSendtime(new Date());
System.out.println(body.toString());
if(StringUtils.isEmpty(chatInfo.getNoticeCode())){
chatInfo.setNoticeCode(UUID.randomUUID().toString());
}
//聊天信息保存到数据库中
service.save(chatInfo);
logger.debug("给消息发送者回复状态完毕--------------------");
if(!webSocketSet.containsKey(chatInfo.getRecid())){
//用户不在线,判断是否是手机用户,如果手机用户则改为个推推送
logger.debug("用户id:"+ chatInfo.getRecid() +"不在线----");
return;
}
//设定接收者的姓名
chatInfo.setRecName(webSocketSet.get(chatInfo.getRecid()).getName());
webSocketSet.get(chatInfo.getRecid()).sendMessage(mapper.writeValueAsString(chatInfo));
} catch (Exception e) {
e.printStackTrace();
logger.debug("解析聊天信息出错",e);
}
}
@OnError
public void onError(Session session,Throwable error) {
logger.debug("连接出错");
logger.debug(error.getMessage());
Iterator it = webSocketSet.entrySet().iterator();
//移除出错的websocket对象
while(it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
if(session==entry.getValue()){
webSocketSet.remove(entry.getKey());
}
}
}
/**
* 给当前用户发送消息
* @param message 消息内容
* @throws IOException 发送消息出错时抛出异常
*/
public void sendMessage(String message) throws IOException{
this.session.getBasicRemote().sendText(message);
}
/**
* 群发消息,给所有在线的用户发送消息
* @param message 需要发送的消息
*/
public static void sendInfo(String message){
logger.debug("群发消息:"+message);
Iterator it = webSocketSet.entrySet().iterator();
while(it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
try {
webSocketSet.get(entry.getKey()).sendMessage(message);
}catch (IOException e){
//群发消息时有发送不成功的,忽略,尽可能发送给全部用户
logger.error("sendInfo1群发消息出错--------------------",e);
}
}
}
/**
* 给指定的列表用户群发消息
* @param userList 用户id列表
* @param message 需要发送的消息
*/
public static void sendInfo(List<Integer> userList,String message){
//给指定的列表用户群发消息
System.out.println("给指定的列表用户群发消息");
for(Integer id:userList){
if(webSocketSet.containsKey(id)){
try {
webSocketSet.get(id).sendMessage(message);
}catch (IOException e){
//发送失败时忽略,将来可能改成发送短信
logger.error("sendInfo2群发消息出错--------------------",e);
}
}
}
}
/**
* 关闭连接,用户退出websocket
*/
public void close(){
if(this.session !=null){
try {
this.session.close();
}catch (Exception e) {
}finally {
this.session = null;
}
}
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public boolean isAppUser() {
return isAppUser;
}
public void setAppUser(boolean appUser) {
isAppUser = appUser;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
WebSocketMessageBody.java
// WebSocketMessageBody.java
package com.xxx.model;
/**
* websocket消息体
*/
public class WebSocketMessageBody<T> {
//消息类型
private Integer type;
//消息数据
private T data;
public Integer getType() {
return type;
}
public void setType(Integer type) {
this.type = type;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
里面的ChatInfo.java内容将在后面文章给出。