说明:WebSocket的通信时每个链接都会在onOpen方法里面建立一个WebSocketSession,当多个session连接的时候,我们就需要对每个session进行唯一性标识(一般一个用户有一个连接)所以就需要创建一个Map<String,Session>来装所有的session并对每个session进行标识。
1:先把页面代码贴出来
<script type="text/javascript">
webSocket = new WebSocket("ws://localhost:8080/WSPMXT/WSHello");
webSocket.onopen =function(event){
if(event.data === undefined)
return;
webSocket.onmessage =function(event){
alert("成功了"+event.data);
};
webSocket.onerror =function(event){
alert("连接错误");
};
webSocket.onclose =function(event){
alert("连接关闭");
};
}
</script>
2:后台代码 首先建一个HelloEndPoint 类进行连接管理,onOpen方法在创建连接的时候使用onMessage方法则是需要给页面发送数据的时候调用
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.websocket.EndpointConfig;
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;
@ServerEndpoint(value="/WSHello",configurator=GetHttpSessionConfigurator.class )
//configurator 指定一个被重写的类 onOpen方法才能使用第二个参数EndpointConfig config ,一般第二个参数用来做Map的KEY
public class HelloEndPoint {
public static final Map<String,Session > users = new HashMap<String, Session>();
//构建一个Map 来装所有链接webSocket的session
@OnOpen
public void onOpen(Session session,EndpointConfig config){
// HttpSession httpSession= (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
String userId= (String) config.getUserProperties().get("sendid");
System.out.println("Session " + session.getId() + " has opened a connection");
users.put(userId, session); //注意 最好是能在session断开连接的时候 将对应得session清除,不然如果KEY值一样的话第二次websocket连接的时候会出错
try {
session.getBasicRemote().sendText("Connection Established");
} catch (IOException ex) {
ex.printStackTrace();
}
}
@OnMessage
public void onMessage(String message, Session session){
try {
session.getBasicRemote().sendText("message");
} catch (IOException ex) {
ex.printStackTrace();
}
}
@OnClose
public void onClose(Session session){
System.out.println("Session " +session.getId()+" has closed!");
}
/**
* 注意: OnError() 只能出现一次. 其中的参数都是可选的。
* @param session
* @param t
*/
@OnError
public void onError(Session session, Throwable t) {
t.printStackTrace();
}
}
3:2中指定了一个重写的类,这里贴出该类的代码
import javax.servlet.http.HttpSession;
import javax.websocket.HandshakeResponse;
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.ServerEndpointConfig;
import javax.websocket.server.ServerEndpointConfig.Configurator;
import javax.websocket.HandshakeResponse;
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.ServerEndpointConfig;
import javax.websocket.server.ServerEndpointConfig.Configurator;
public class GetHttpSessionConfigurator extends Configurator {
//继承Configurator 重写下面的方法完成逻辑代码,比如将HttpSession或者Cookie传过去或者其他类的一些业务数据比如下面我将传递一个UserId过去
//继承Configurator 重写下面的方法完成逻辑代码,比如将HttpSession或者Cookie传过去或者其他类的一些业务数据比如下面我将传递一个UserId过去
@Override
public void modifyHandshake(ServerEndpointConfig sec,
HandshakeRequest request, HandshakeResponse response) {
// HttpSession httpSession=(HttpSession) request.getHttpSession();//获取HttpSession
// sec.getUserProperties().put(HttpSession.class.getName(),httpSession); //将session装进sec,在webSocket主类里onOpen方法里调用这个对象
SendUserId si = new SendUserId();
String id = si.sendId();
sec.getUserProperties().put("sendid",id);
}
}
public void modifyHandshake(ServerEndpointConfig sec,
HandshakeRequest request, HandshakeResponse response) {
// HttpSession httpSession=(HttpSession) request.getHttpSession();//获取HttpSession
// sec.getUserProperties().put(HttpSession.class.getName(),httpSession); //将session装进sec,在webSocket主类里onOpen方法里调用这个对象
SendUserId si = new SendUserId();
String id = si.sendId();
sec.getUserProperties().put("sendid",id);
}
}
4:调用2中的onMessage方法向页面传递数据
import javax.websocket.Session;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import com.zsq.webSocket.HelloEndPoint;
import com.zsq.webSocket.SendUserId;
import com.zsq.webSocket.SendUserId;
@Controller("Sse")
public class TestSseController {
public class TestSseController {
@RequestMapping(value="websocket")
protected String sendMesage(){
SendUserId si = new SendUserId();
String id = si.sendId();
HelloEndPoint hep = new HelloEndPoint();
Session session = hep.users.get(id); //根据userid获取相应的session用这个session传值给指定的用户
String message = "成功";
hep.onMessage(message,session);
protected String sendMesage(){
SendUserId si = new SendUserId();
String id = si.sendId();
HelloEndPoint hep = new HelloEndPoint();
Session session = hep.users.get(id); //根据userid获取相应的session用这个session传值给指定的用户
String message = "成功";
hep.onMessage(message,session);
return "index";
}
}
}
}
5:这里提及一下SSE,这是一种服务器单向推送数据到浏览器的技术。我之前也用过但是,SSE推送数据浏览器接收后会再想服务器发送一个请求,这一点很不爽。