java7+tomcat7+springmvc4.3的初次websocket试验(二)

本文介绍了一个基于Spring框架的WebSocket聊天室应用实现过程。包括创建控制器类处理HTTP请求、修改拦截器和处理器类以支持WebSocket连接,以及前端JavaScript代码用于建立WebSocket连接并发送消息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

昨天试验的内容是直接通过handler接收和发送消息。

今天继续试验。试验内容是加一个controller类,处理页面正常的http请求。

1.新建controller类

package com.test.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.socket.TextMessage;
import com.alibaba.fastjson.JSONObject;
import com.test.utils.HttpUtil;
import com.test.ws.MyWebSocketHandler;

@Controller
public class SocketController {
@Autowired
private MyWebSocketHandler myWebSocketHandler;

    /**
* 此处用orderno参数做id来区分不同的广播频道(或者说聊天室频道等)
* @param session httpSession 
* @param orderno 频道id
* @param request
* @param response
*/

@ResponseBody
@RequestMapping(value="/login/{orderno}")
public void login(HttpSession session, @PathVariable("orderno") String orderno, HttpServletRequest request, HttpServletResponse response){
System.out.println("orderno:" + orderno);
response.setContentType("application/json");

// 处理本次请求的相关业务,如数据库的增删改查等


// 处理完成后,向其他在同频道的人广播
// 要发送内容
JSONObject obj = new JSONObject();
obj.put("test", "test1");
obj.put("orderno", orderno);
try {
myWebSocketHandler.sendMsgToAllUsersByOrder(orderno, new TextMessage(obj.toString()));
} catch (Exception e) {
e.printStackTrace();
}

// 本次请求的处理返回内容
HttpUtil.writeJson(HttpUtil.getJsonSuccess().toString(), response);
}
}

只是一种写法,其实可以单纯的写成一般的controller类就行。

比如定义方法: public void doSomething(HttpServletRequest req, HttpServletResponse res){

}

2.修改handlerInterceptor

package com.test.ws;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;

public class HandshakeInterceptor extends HttpSessionHandshakeInterceptor {
// 在握手之前执行该方法, 继续握手返回true, 中断握手返回false. 通过attributes参数设置WebSocketSession的属性
    @Override
    public boolean beforeHandshake(ServerHttpRequest request,
            ServerHttpResponse response, WebSocketHandler wsHandler,
            Map<String, Object> attributes) throws Exception {

        System.out.println(" HandshakeInterceptor: beforeHandshake "+attributes);


        // 从request中取得参数,orderno作为区分不同广播频道的id,将其设置到attributes参数中,

        if (request instanceof ServletServerHttpRequest) {
        System.out.println("request instanceof ServletServerHttpRequest");
            HttpServletRequest req = ((ServletServerHttpRequest) request).getServletRequest();
            
            String orderid= req.getParameter("orderno");
            System.out.println("request get orderid:" + orderid);
            attributes.put("order_id", orderid);
        }
        return super.beforeHandshake(request, response, wsHandler, attributes);
    }

    // 握手后
    @Override
    public void afterHandshake(ServerHttpRequest request,
            ServerHttpResponse response, WebSocketHandler wsHandler,
            Exception ex) {
        System.out.println(" HandshakeInterceptor: afterHandshake ");
        super.afterHandshake(request, response, wsHandler, ex);
    }
}

3.修改handler类

package com.test.ws;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

public class MyWebSocketHandler implements WebSocketHandler {

    private static final Map<String,Set<WebSocketSession>> orderSession;
    
    static{
    orderSession = new HashMap<String,Set<WebSocketSession>>();
    }

    // 关闭 连接时
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus arg1)
throws Exception {
System.out.println("session:" + session.getId() + "  connect websocket closed.......");
removeSession(session);
}

// 连接 就绪时 
@Override
public void afterConnectionEstablished(WebSocketSession session)
throws Exception {
System.out.println("connect websocket success.......");
if (!hasSession(session)){
putSession(session);
}
}

// 处理客户端发来的信息
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message)
throws Exception {
// 无此功能需求
Gson gson = new Gson();

        // 将消息JSON格式通过Gson转换成Map
        // message.getPayload().toString() 获取消息具体内容
        Map<String, Object> msg = gson.fromJson(message.getPayload().toString(), 
                new TypeToken<Map<String, Object>>() {}.getType());
        System.out.println("handleMessage......."+message.getPayload()+"..........."+msg);
        session.sendMessage(message);
        // 处理消息 msgContent消息内容
        TextMessage textMessage = new TextMessage(msg.get("msgContent").toString(), true);
        String orderno = getOrderno(session);
        // 调用方法(发送消息给所有人)
        sendMsgToAllUsersByOrder(orderno, textMessage);
}

// 处理传输时异常
@Override
public void handleTransportError(WebSocketSession session, Throwable arg1)
throws Exception {
System.out.println("session:" + session.getId() + "  handleTransportError");
}

@Override
public boolean supportsPartialMessages() {
return false;
}

// 给该orderno页面的所有用户发送 信息
    public void sendMsgToAllUsersByOrder(String orderno, WebSocketMessage<?> message) throws Exception{
    if(!orderSession.isEmpty() && orderSession.containsKey(orderno)){
    Set<WebSocketSession> orderSet = orderSession.get(orderno);
    Iterator<WebSocketSession> orderIt = orderSet.iterator();
    while(orderIt.hasNext()){
    WebSocketSession session = orderIt.next();
    session.sendMessage(message);
    }
    }
    }
    
    private String getOrderno(WebSocketSession session){
    return  (String) session.getAttributes().get("order_id");
    }
    
    private boolean hasSession(WebSocketSession session){
    if(orderSession.isEmpty()){
    return false;
    } else {
    String orderno = getOrderno(session);
    if (orderSession.containsKey(orderno)){
    Set<WebSocketSession> orderSet = orderSession.get(orderno);
    if(orderSet.contains(session)){
    return true;
    } else {
    return false;
    }
    } else {
    return false;
    }
    }
    }
    
    private void putSession(WebSocketSession session){
    String orderno = getOrderno(session);
    if (orderSession.isEmpty() || !orderSession.containsKey(orderno)){
    Set<WebSocketSession> orderSet = new HashSet<WebSocketSession>();
    orderSet.add(session);
   
    orderSession.put(orderno, orderSet);
    } else {
    Set<WebSocketSession> orderSet = orderSession.get(orderno);
    orderSet.add(session);
   
    orderSession.put(orderno, orderSet);
    }
    }
    
    private void removeSession(WebSocketSession session){
    String orderno = getOrderno(session);
    if (!orderSession.isEmpty() && orderSession.containsKey(orderno)){
    Set<WebSocketSession> orderSet = orderSession.get(orderno);
    orderSet.remove(session);
    if (!orderSet.isEmpty()){
    orderSession.put(orderno, orderSet);
    } else {
    orderSession.remove(orderno);
    }
   
    }
}

4.修改页面上的js

<!DOCTYPE HTML>
<html>
    <head>
        <title>首页</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta name="renderer" content="webkit">
        <!-- 引入 JQuery  -->
        <script type="text/javascript" src="E:\test\jquery-3.3.1.min.js"></script>
        <!-- 引入 sockJS  
        <script type="text/javascript" src="sockjs.min.js" ></script>-->

        <!-- 自定义JS文件 -->
        <script type="text/javascript" >
$(function() {
var websocket;
                                // 正常用ajax去调用http请求
$.ajax({url:"http://localhost:8080/testSpringWebsocket/login/4",
type:"POST",
data: {'usr':'123'},
dataType:'json',

success:function(result){

                                        // ajax处理正常时,建立websocket链接,链接成功后就可以发送消息和接收消息

// 首先判断是否 支持 WebSocket。
if('WebSocket' in window) {
websocket = new WebSocket("ws://localhost:8080/testSpringWebsocket/websocket?orderno=4");
} else if('MozWebSocket' in window) {
websocket = new MozWebSocket("ws://localhost:8080/testSpringWebsocket/websocket?orderno=4");
} else {
websocket = new SockJS("http://localhost:8080/testSpringWebsocket/sockjs/websocket?orderno=4");
}

// 打开时
websocket.onopen = function(evnt) {
console.log("  websocket.onopen  ");
};

// 处理消息时
websocket.onmessage = function(evnt) {
$("#msg").append("<p>(<font color='red'>" + evnt.data + "</font>)</p>");
console.log("  websocket.onmessage   ");
};
websocket.onerror = function(evnt) {
console.log("  websocket.onerror  ");
};
websocket.onclose = function(evnt) {
console.log("  websocket.onclose  ");
};
// 点击了发送消息按钮的响应事件
$("#TXBTN").click(function(){
// 获取消息内容
var text = $("#tx").val();
// 判断
if(text == null || text == ""){
alert(" content  can not empty!!");
return false;
}
var msg = {
msgContent: text,
postsId: 1
};
// 发送消息
websocket.send(JSON.stringify(msg));
});
}});
});
</script>
    </head>
    <body>
        <!-- 最外边框 -->
        <div style="margin: 20px auto; border: 1px solid blue; width: 300px; height: 500px;">
            <!-- 消息展示框 -->
            <div id="msg" style="width: 100%; height: 70%; border: 1px solid yellow;overflow: auto;"></div>
            <!-- 消息编辑框 -->
            <textarea id="tx" style="width: 100%; height: 20%;"></textarea>
            <!-- 消息发送按钮 -->
            <button id="TXBTN" style="width: 100%; height: 8%;">发送数据</button>
        </div>
    </body>
</html>

5.spring.xml文件中

<!-- websocket处理类 -->

<bean id="myHandler" class="com.test.ws.MyWebSocketHandler"/>

目前有个疑问,用注解方式,tomcat启动报错,也不能访问。尝试过的注解有@Component和@Service。两个都不行。暂时没去解决。等有时间再看。


昨天的第一次试验的内容:https://blog.youkuaiyun.com/bengdird/article/details/79655314

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值