websocket踩坑记录

由于写的app须要用到信息推送的功能
        因此负责交互的我就开始找相关的解决方案。
        首先想到的是最近接触比较多的http请求
        可是由于http请求的get与post都是短链接
        若是作while循环sleep fetch 的话
        效率会极为的低下
        耗电高
        还会比较消耗流量
        因此在尝试着弄出来http版的伪“推送”以后
        咱们想到了socket这个东西。

        尝试了一下socket
        我发现web的项目并不能使用这个东西
        后来我想到了之前弄rn接触到的websocket
        仔细研究了一下
        之前看不懂的地方如今已是能轻松理解了
        <这里必需要感慨一下成长果真是阶段性的>
        因而就开始了websocket的踩坑之旅。。。

        首先第一个坑是实现。
        由于websocket 你们都是想着 b/s 
        可是。。咱们须要在app中用java代码
        实现相关websocket的client端。
        因而就开始踩坑了。。。
        后来用了一个别人的jar包解决了这个问题
        而且实现了信息的群推

        可是我倒是没有弄清关键的需求
        致使弄出来的并非咱们想要的
        我觉得要的是群发效果
        结果***却说要的是qq同样的点发
        而后就开始进入第二个踩坑阶段,点对点

        首先,这个点对点须要一个标识id
        以此来区别session 的身份
        而后就开始疯狂的百度。
        找了一段时间找到了想要的
        第一坑填上。。。

        而后就是怎么在服务器上让本身持有一个推送的管道
        这里我试了好久,
        脑中有两种想法
        一种就是服务端持有一个内部client
        而后走send达成群发
        一个就是直接调用服务端的群发函数,
        由服务端给客户端直接发送
        可是第二个我试了却没效果。。。
        很纳闷
        而后就是第一个
        又是百度了好久
        最后终因而被我捣鼓出来了。。。

        下面上源码吧,有须要的人确定用得上的

WsocketClient.java
 
 
package test;
import javax.websocket.ClientEndpoint;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
@ClientEndpoint
public class WsocketClient {
    @OnOpen  
     public void onOpen(Session session) {  
         System.out.println("Connected to endpoint: " + session.getBasicRemote());  
     }  
    
     @OnMessage  
     public void onMessage(String message) {  
         System.out.println(message);  
     }  
    
     @OnError  
     public void onError(Throwable t) {  
         t.printStackTrace();  
     }  
}

Wsocket_boardCast.java
package test;
import java.io.IOException;
import java.net.URI;
import javax.websocket.ContainerProvider;
import javax.websocket.DeploymentException;
import javax.websocket.Session;
import javax.websocket.WebSocketContainer;
import com.google.gson.Gson;
public class Wsocket_boardCast  {
     public static Session session;  
    
    public static void sendMes(String Mess){
        if(session==null){
            WebSocketContainer container = ContainerProvider.getWebSocketContainer();  
             String uri = "ws://localhost:8080/Novel_Servlet/websocket?id=robot_007";  
             try {  
                 session = container.connectToServer(WsocketClient.class, URI.create(uri));  
                 
             } catch (DeploymentException e) {  
                 e.printStackTrace();  
             } catch (IOException e) {  
                 e.printStackTrace();  
             } 
        }
        Mes mes = new Mes();
        mes.setContent(Mess);
        mes.setFrom("robot_007");
        mes.setTo("");
        String str = new Gson().toJson(mes);
        session.getAsyncRemote().sendText(str); 
    }
}


Wsocket.java //servlet

package servlet;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import javax.servlet.http.HttpServlet;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import com.google.gson.Gson;
import test.Mes;
@ServerEndpoint("/websocket") 
public class Wsocket extends HttpServlet{
    /**
     * 
     */
    private static final long serialVersionUID = -3223301982392555858L;
    private static ConcurrentMap<String,Wsocket>users = new ConcurrentHashMap<>();  
    private String id;  
    private Session session;  
    
    @OnOpen  
    public void onOpen(Session session) throws IOException{   
        this.session = session;  
        Map<String,List<String>>map = session.getRequestParameterMap();  
        id = map.get("id").get(0);  
        users.put(id, this);  
        List<String>list =new ArrayList<>(users.keySet());
        Set<String>key = users.keySet();  
        for(String k: key){  
            users.get(k).sendMessage(new Gson().toJson(list).toString());  
        }  
    }  
    
    @OnClose  
    public void onClose(){  
        users.remove(id);
    }  
    
     @OnMessage  
        public void onMessage(String message, Session session) throws IOException {   
            System.out.println("收到来自客户端的信息:" + message);  
            Mes mes = new Gson().fromJson(message, Mes.class);   
            if(mes.getTo().isEmpty()){  
                Set<String>key = users.keySet();  
                for(String k: key){  
                    if(k.equals(mes.getFrom()))continue;  
                    users.get(k).sendMessage(message);  
                }  
            }else{  
                Wsocket toServlet = users.get(mes.getTo());  
                if(null!=toServlet){  
                    toServlet.sendMessage(message);  
                }  
            }  
        }  
     
     @OnError  
        public void onError(Session session, Throwable error){  
            System.out.println("Error");  
            error.printStackTrace();  
        }  
     
     public void sendMessage(String message) throws IOException{  
            this.session.getAsyncRemote().sendText(message);  
            //this.session.getAsyncRemote().sendText(message);  
        }  
}

jsp网页
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <div id="to">发送给:[<span class="users">全部人</span>]</div>  
    <div id='container'>  
        <div id="left_panel">  
            <div id="left_top">  
                <!-- <div class="mes from_me">FROM ME</div>  
                <div class="mes to_me">TO ME</div> -->  
            </div>  
              
            <div id="left_bottom" contentEditable="true"></div>  
        </div>  
        <div id="right_panel">  
            <div id="right_top">  
                  
            </div>  
            <div id="right_bottom">  
                <input type="text" id="user_name" placeholder="User Name" maxlength="10" required/>  
                <input type="button" id="login" value="登陆" onclick="login()"/>  
            </div>  
        </div>  
          
    </div>  
    <script>  
        var userName;  
        var toUser="";  
        var websocket=null;  
        function choose(arg){  
            toUser=arg.innerHTML;  
            document.getElementById("to").innerHTML='发送给:[<span class="users">'+toUser+'</span>]';  
            if(toUser==='全部人')toUser='';  
        }  
        function login(){  
            if(!document.getElementById("user_name").checkValidity())return ;  
            userName = document.getElementById("user_name").value;  
            if(userName=="")return;  
            ws();  
        }  
        function ws(){  
            if('WebSocket' in window){  
                websocket = new WebSocket("ws://"+location.host+"/Novel_Servlet/websocket?id="+userName);  
                websocket.onopen = function(event){  
                    console.log("websocket open");  
                    var opt = document.getElementById("right_bottom");  
                    opt.innerHTML='<input type="button" id="login" value="发送" onclick="send()" style="margin-top:50px" />';  
                }  
                websocket.onerror = function(){  
                     console.log("websocket error");  
                     alert("登陆失败");  
                };   
                websocket.onclose = function(){  
                    console.log("websocket close");  
                    var opt = document.getElementById("right_bottom");  
                    opt.innerHTML='<input type="text" id="user_name" placeholder="User Name" maxlength="10" required/>
<input type="button" id="login" onclick]="login()" value="登陆"/>';  
                };     
                websocket.onmessage = function(e){  
                    var json = JSON.parse(e.data);  
                    if((typeof json.to) == 'undefined'){  
                        var html = '<div class="users" onclick="choose(this)">全部人</div>';  
                        for(var k in json){  
                            html+='<div class="users" onclick="choose(this)">'+json[k]+'</div>';  
                        }  
                        document.getElementById("right_top").innerHTML=html;  
                    }else{  
                        var record = document.getElementById("left_top");  
                        var html = '<div class="mes to_me">'+json.from+' : '+json.content+'</div>';  
                        record.innerHTML+=html;  
                    }  
                };  
            }else alert("Not Support!");  
        }  
        window.onbeforeunload = function(){  
            if(null!=websocket)  
                websocket.close();  
        };  
        function send(){  
            var input = document.getElementById("left_bottom");  
            var mes={  
                from:userName,  
                to:toUser,  
 
                content:input.innerHTML
            };  
            if(null!=websocket)websocket.send(JSON.stringify(mes));  
            var html = '<div class="mes from_me">'+userName+' : '+input.innerHTML+'</div>';  
            document.getElementById("left_top").innerHTML+=html;  
            input.innerHTML='';  
        }  
    </script>  
</body>
</html>

Mes.java //bean
package test;
public class Mes {
    private String to;
    private String from;
    private String content;
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
    public String getTo() {
        return to;
    }
    public void setTo(String to) {
        this.to = to;
    }
    public String getFrom() {
        return from;
    }
    public void setFrom(String from) {
        this.from = from;
    }
}

测试触发系统广播的servlet

package servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import test.Wsocket_boardCast;
//import test.Wsocket_boardCast;
/**
 * Servlet implementation class Czx
 */
@WebServlet(description = "这个是测试触发的servlet", urlPatterns = { "/Czx" })
public class Czx extends HttpServlet {
    private static final long serialVersionUID = 1L;
//  private Session session;
    /**
     * Default constructor. 
     */
    public Czx() {
        // TODO Auto-generated constructor stub
    }
    @Override
    public void init(){
              
        
    }
    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub 
        Wsocket_boardCast.sendMes("Robot全员广播");   
        
    }
    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(request, response);
    }
}

之后打算就写在这里吧~
慢慢搬文章。。。。
固然还有填掉之前的坑~