所有分类
  • 所有分类
  • 后端开发
传统 web.xml 配置方式与 MyWebSocketServlet 实现前台后台请求交互

传统 web.xml 配置方式与 MyWebSocketServlet 实现前台后台请求交互

这里没有使用注解,传统的web.xml配置方式,首先在系统启动的时候调用InitServlet方法通过以上代码,就可以实现一个点对点的聊天功能,如果做的大,可以做成一个web版的聊天系统,包括聊天室和单人聊天,都说websocket不支持二

早先搞网页开发时,最常用的就是那个叫web.xml的玩意儿,它好比项目的开机设置,告诉服务器怎么启动,该装哪些servlet。那时咱还得运行个叫InitServlet的东东,给服务器上点油,加载一些配置,连通数据库这些事情都是它负责搞定。这种做法虽然历史悠久,但质量过硬,很多老项目至今仍有它的身影!

不过这招也有烦人的地方,就是得重启服务器才能生效,这个可对我们的编程生活造成困扰。另外,项目变得越复杂,Web.xml文件就越大,越难维护了。所以,现在好多新的项目都喜欢用注解代替那个旧的Web.xml方法!

public class InitServlet extends HttpServlet {
    private static final long serialVersionUID = -3163557381361759907L;  
    private static HashMap socketList;    
    public void init(ServletConfig config) throws ServletException {    
        InitServlet.socketList = new HashMap();    
        super.init(config);    
        System.out.println("初始化聊天容器");    
    }    
    public static HashMap getSocketList() {    
        return InitServlet.socketList;    
    }    
}

WebSocket的基本概念

WebSocket这个词有些人听着可能比较新鲜,意思就是我可以在咱们的网上聊天,就用一个TCP连接就好,两边可以发信息也能收,不像传统HTTP那样,得重新连一次才能继续聊~


    
        websocket
        socket.MyWebSocketServlet
    
    
        websocket
        *.do
    
    
        initServlet
        socket.InitServlet
        1
    
    
        index.jsp
    

WebSocket最赞的地方就在它实时传输信息。想想看,如果是用HTTP,我们的聊天系统就得不断重建连接,那得多慢呐!但换了WebSocket,服务器和客户端就能一路畅通无阻,随时随地发消息收消息,这用户感受岂不是立马飞起?

MyWebSocketServlet的实现

搞定WebSocket时,你可能会用到叫作”MyWebSocketServlet”的类,它就像个小王子,头脑聪明,能直接继承HttpServlet,处理那些源源不断的客户端请求。这个类里头还有个更厉害的角色,就是”MyMessageInbound”类,这位兄弟直接从MessageInbound那里继承下来,专门负责处理来自客户端的文本消息。

咱们在onTextMessage這個方法里头,可以對用户发过来的信息下手,我们可以把它们解析出来,封包到一起,最后把消息传递过去。这样子咱们就能轻松搞定聊天这个事儿了。不过要是想做出牛逼点的聊天系统,光这么干可不够,还要搞定好多别的事,比如说怎么管理用户,如何储存消息之类的。

public class MyWebSocketServlet extends WebSocketServlet {
    public String getUser(HttpServletRequest request){
        String userName = (String) request.getSession().getAttribute("user");
        if(userName==null){
            return null;
        }
        return userName;  
    }  
    protected StreamInbound createWebSocketInbound(String arg0,
            HttpServletRequest request) {
        System.out.println("用户" + request.getSession().getAttribute("user") + "登录");
        return new MyMessageInbound(this.getUser(request)); 
    }
}

前台与后台的交互

WebSocket里头,前后台交流可不能少。前台是用JavaScript搞起来的,靠着WebSocket对象来发信息收信息。后台嘛就得用Java搭个平台,用上MyWebSocketServlet和MyMessageInbound就能搞定前台给过来的消息了。

咱们在前台得按规矩发信息!比如说,咱用个JSON格式,写明啥消息,说啥话。后台接到信儿后,就能看是啥种类,然后去处理咯。这样一来,前台和后台就能好好交流。

package socket;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.util.HashMap;
import org.apache.catalina.websocket.MessageInbound;
import org.apache.catalina.websocket.WsOutbound;
import util.MessageUtil;
public class MyMessageInbound extends MessageInbound {
    private String name;
    public MyMessageInbound() {
        super();
    }
    public MyMessageInbound(String name) {
        super();
        this.name = name;
    }
    @Override  
    protected void onBinaryMessage(ByteBuffer arg0) throws IOException {  
    }  
    @Override  
    protected void onTextMessage(CharBuffer msg) throws IOException { 
        //用户所发消息处理后的map
        HashMap messageMap = MessageUtil.getMessage(msg);    //处理消息类
        //上线用户集合类map
        HashMap userMsgMap = InitServlet.getSocketList();
        String fromName = messageMap.get("fromName");    //消息来自人 的userId
        String toName = messageMap.get("toName");         //消息发往人的 userId
        //获取该用户
        MessageInbound messageInbound = userMsgMap.get(toName);    //在仓库中取出发往人的MessageInbound
        MessageInbound messageFromInbound = userMsgMap.get(fromName);
        if(messageInbound!=null && messageFromInbound!=null){     //如果发往人 存在进行操作
            WsOutbound outbound = messageInbound.getWsOutbound(); 
            WsOutbound outFromBound = messageFromInbound.getWsOutbound();
            String content = messageMap.get("content");  //获取消息内容
            String msgContentString = fromName + "说: " + content;   //构造发送的消息
            //发出去内容
            CharBuffer toMsg =  CharBuffer.wrap(msgContentString.toCharArray());
            CharBuffer fromMsg =  CharBuffer.wrap(msgContentString.toCharArray());
            outFromBound.writeTextMessage(fromMsg);
            outbound.writeTextMessage(toMsg);  //
            outFromBound.flush();
            outbound.flush();
        }
    }  
    @Override  
    protected void onClose(int status) {  
        InitServlet.getSocketList().remove(this);  
        super.onClose(status);  
    }  
    @Override
    protected void onOpen(WsOutbound outbound) {  
        super.onOpen(outbound);  
        //登录的用户注册进去
        if(name!=null){
            InitServlet.getSocketList().put(name, this);//存放客服ID与用户
        }
    }
    @Override
    public int getReadTimeout() {
        return 0;
    }  
}

传统 web.xml 配置方式与 MyWebSocketServlet 实现前台后台请求交互

A.jsp页面与B.jsp页面的实现

聊吧功能咋做?就得用上咱俩,A页面还有那个B页面。这俩页面都能发消息也能接,就能实现一对一的私聊了!

你看,在A.jsp页面里,咱们能用JavaScript玩转WebSocket,连接服务器,发传讯息之类的都行。而到了B.jsp页面,用的还是这套本领,这不,两个页面能互相发聊天信息!

聊天系统的扩展

package util;
import java.nio.CharBuffer;
import java.util.HashMap;
public class MessageUtil {
    public static HashMap getMessage(CharBuffer msg) {
        HashMap map = new HashMap();
        String msgString  = msg.toString();
        String m[] = msgString.split(",");
        map.put("fromName", m[0]);
        map.put("toName", m[1]);
        map.put("content", m[2]);
        return map;
    }
}

搞定个大型聊天系统可没那么简单,比如说网上那种聊天平台啥的,我们得做好一大堆工作!首先就是要搞好用户管理,还要有个装消息的地方,另外不能少了聊天室这个重要部分哇。

关于用户管理,就是把大家的个人资料比如用户名啊、密码啦、头像啥之类的东西存在数据库里头;说到底就是帮你存和找那些消息的人是谁,什么时候发的消息,都在这里搞定。再说到那个聊天室功能,通过WebSocket就可以让大家随时随地跟别人聊嗨皮!

WebSocket与二进制传输

在WebSocket上,我们能用二进制传输方式传送并接收数据,比如能把ArrayBuffer当作载体传输二进制内容,GetBlob来获取它们。





Index



var ws = null;
function startWebSocket() {
    if ('WebSocket' in window)
        ws = new WebSocket("ws://localhost:8080/WebSocketUser/websocket.do");
    else if ('MozWebSocket' in window)
        ws = new MozWebSocket("ws://localhost:8080/WebSocketUser/websocket.do");
    else
        alert("not support");
    ws.onmessage = function(evt) {
        //alert(evt.data);
        console.log(evt);
       // $("#xiaoxi").val(evt.data);
        setMessageInnerHTML(evt.data);
    };
    function setMessageInnerHTML(innerHTML){
        document.getElementById('message').innerHTML += innerHTML + '
'; } ws.onclose = function(evt) { //alert("close"); document.getElementById('denglu').innerHTML="离线"; }; ws.onopen = function(evt) { //alert("open"); document.getElementById('denglu').innerHTML="在线"; document.getElementById('userName').innerHTML='小化'; }; } function sendMsg() { var fromName = "小化"; var toName = document.getElementById('name').value; //发给谁 var content = document.getElementById('writeMsg').value; //发送内容 ws.send(fromName+","+toName+","+content);//注意格式 }

聊天功能实现

登录状态: 正在登录
登录人:


发送给谁:
发送内容:
聊天框:


虽然WebSocket能传二进制,但实际上咱日常开发中基本不用这功能。为啥?虽说是可以快那么点,可是编程的难度也上去了不少。所以大部分时候,咱们还是选文本传输,方便省事。

JavaScript与二进制传输

在JavaScript里,咱们可用FileReader把那些binarydata读出来。其实,JavaScript自己不支援bin格式的传输,但FileReader这个玩意儿就帮咱解决了这个问题,终于得以手拿着binarydata进行操作!

其实,咱们平时很少用FileReader这个东西。毕竟,二进制文件处理起来太麻烦了,还经常搞错。所以,大部分时候,咱们都是用纯文字数据来交流跟操作。

原文链接:https://www.icz.com/technicalinformation/web/javascript/2024/07/19645.html,转载请注明出处~~~
0

评论0

请先
注意:请收藏好网址www.icz.com,防止失联!站内免费资源持续上传中…!赞助我们
显示验证码
没有账号?注册  忘记密码?