websocket长连接

场景应用:客户端下订单后需要即时通知后台,弹框提示有新订单生成

解决办法:1、以前采用技术是轮询方式,浏览器以特定的时间间隔(如每隔1秒)向服务器(ajax方式)发送请求,这种方式缺点就是需要不断向服务器发送请求,耗用服务器资源;

2、采用websocket方式,浏览器和服务器只需要做个一握手动作,然后二者之间就形成了一条快速通道,这就好比说我和你握手,我如果有个什么晃动,你那儿马上也感知到了。这样的好处就是服务器不再被动接受浏览器的请求,而是只要有新数据就主动发送给浏览器,并且不用占用大量资源。

下面举个简单的例子:


第一步:浏览器端代码

function orderTips(pa1,pa2,pa3) {//pa1,pa2,pa3是建立握手之初发送服务器的参数
   
         var webSocket = new WebSocket("ip:port/webProjectName/websocket/'+pa1+'/'+pa2+'/'+pa3);
         
      webSocket.onerror = function(event) {
         onError(event)
      };
  
      webSocket.onopen = function(event) {
         onOpen(event)
      };
  
      webSocket.onmessage = function(event) {
         onMessage(event)
      };
  
      //接收服务端发送过来的信息
      function onMessage(event) {
       var type = event.data; 
       if(type == '1'){
             //业务1;
     }else if(type == '2'){
             //业务2;
     }else{
             //业务3
     }
   }
  
      function onOpen(event) {
      }
  
      function onError(event) {
      }
  
      function start() {
          return false;
      }
  }

 

第二步:服务器端,建立WebSocket类

 

@ServerEndpoint(value = "/websocket/{pa1}/{pa2}/{pa3}")
public class WebSocket {
 
 //当前在线数
 private static int onlineCount = 0;
 
 //set集合保存websocket实例
 private static CopyOnWriteArraySet<WebSocket> wsSet = new CopyOnWriteArraySet<WebSocket>();

 
 private Session session;
  

 /**
  * 接收到客户端发来的消息并处理,同时也向客户端发送消息
  */
 @OnMessage
    public void onMessage(String message , Session session)
     throws IOException, InterruptedException {
  this.session = session;
  System.out.println("**********客户端发来的消息**********: " + message);
  System.out.println("**********websocket数量*********:" + wsSet.size());
  
  //群发消息
  for(WebSocket ws : wsSet){//循环websocket过滤权限
        if() {//权限范围之内接收消息提示

             ws.sendMessage(message);

        }  

    }
  
  }
 /**
  * 发送消息给客户端
  * @param message
  */
 public void sendMessage(String message) {
  try {
   this.session.getBasicRemote().sendText(message);
   System.out.println("****websocket发送消息****:" + message);
  } catch (Exception e) {
   System.out.println(e.getMessage());
  }
 }
 
 /**
  * 客户端新建websocket时触发
  * 并加入当前的set集合中
  * @param session
  */
 @OnOpen
    public void onOpen (@PathParam("pa1") String pa1,@PathParam("pa2")String pa2,Session session) {
  this.session = session;
  this.setPa1(pa1);
  this.setPa2(Pa2);
  wsSet.add(this);//加入集合
  addOnlineCount();//在线人数+1
  }

 /**
  * 连接关闭时wsSet删除,并且连接数-1
  */
    @OnClose
    public void onClose () {
     wsSet.remove(this); //删除
     subOnlineCount(); // 在线人数-1
    }

    /**
     * websocket错误的时候丢出一个异常
     * @param session
     * @param throwable
     */
    @OnError
    public void wsError(Session session, Throwable throwable) { throw new IllegalArgumentException(throwable);
    System.out.println("onError");
    }
   
   
    /**
     * 有新订单时触发该方法,并调用onMessage发送通知给浏览器端
     * @param msg
     */
 public void triggerEvent(String msg,String pa1) {
  try {
   this.pa1 = pa1;
   onMessage(msg, session);
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
 
 /**
  * 获取当前连接数量
  */
 public static synchronized int getOnlineCount() {
   return onlineCount;
 }
 
 /**
  * 线上人数+1
  */
 public static synchronized void addOnlineCount() {
  WebSocket.onlineCount++;
 }
 
 /**
  * 线上人数-1
  */
 public static synchronized void subOnlineCount() {
  WebSocket.onlineCount--;
 }
 
 private String pa1;
 private String pa2;
 
 public String getPa1() {
  return pa1;
 }
 public void setPa1(String pa1) {
  this.pa1 = pa1;
 }
 public String getPa2() {
  return pa2;
 }
 public void setPa2(String pa2) {
  this.pa2 = pa2;
 }
 }

 第三步:客户端在下订单调用接口后起线程调用WebSocket里的triggerEvent方法

public String subOrder(){//提交订单接口

     new Thread(new Websockets("参数")).start(); //起线程通知后台有新订单

}

class Websockets implements Runnable{

  private String pa1;
  public Websockets (String pa1){
   this.pa1 = pa1;
  }

  @Override
  public void run() {
   WebSocket nn = new WebSocket();
   try {
    nn.triggerEvent("3",pa1); //1、2、3订单类型,pa1可能用到的参数
   } catch (Exception e) {
    e.printStackTrace();
   }
  }
 }

 

总结一下,上面的应用情形比较简单,也只是个人结合网上资料做的一个小例子,经过实证可以运行,有什么不对的地方还希望过往看客能够指正

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值