微信小程序整合WebScoket部署上线

微信小程序整合WebScoket部署上线

在部署的服务器 中安装nginx,并作出如下配置:

思路:

此处监听的是外部的443端口和xcxapi.wfeifei.com域名,当通过该域名和端口号进行访问时,Nginx就会反向代理到,自己项目的端口和服务器上,所以此处项目使用的端口是8081,不可与Nginx监听的端口一样,否则就会冲突

	  
server
 {
	
    listen 443 ssl;#监听外部访问的443
    server_name xcxapi.wfeifei.com;#监听外部访问的域名
 
   #此处的SSL证书使用的是Nginx的配置方式,使用这种方式,就可以不使用tomacat的配置了
    #在nginx的目录下创建,cert文件夹,将对应证书文件放过来,这一步不会的可以百度:Nginx配置SSL证书,或者参考阿里云官网
    
    ssl_certificate /usr/local/nginx/cert/5769555_xcxapi.wfeifei.com.pem;
    ssl_certificate_key /usr/local/nginx/cert/5769555_xcxapi.wfeifei.com.key;
    #上面两项需要替换为自己的SSL证书
    
    ssl_session_timeout 5m;
    ssl_session_cache shared:SSL:50m;
    ssl_protocols SSLv3 SSLv2 TLSv1 TLSv1.1 TLSv1.2; 
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_prefer_server_ciphers on;
    
	#wss协议跳转ws
	#注:这里我的webscoket的接口地址会附在下面,可作为参考
    
    location /websocket/  {   
    proxy_pass http://xcxapi.wfeifei.com:8081/websocket/;
    proxy_http_version 1.1;    
    proxy_set_header Upgrade $http_upgrade;    
    proxy_set_header Connection "Upgrade";    
    proxy_set_header X-real-ip $remote_addr;
    proxy_set_header X-Forwarded-For $remote_addr;
	proxy_read_timeout 600s; #后端服务器处理请求的时间,即webscoket多久会自动断开连接
   }
	 
	 
	 #反向代理接口API
	 #这里配置的就是项目所有的接口,将接口反向代理出去
	location / {
 	   proxy_pass http://xcxapi.wfeifei.com:8081;
   	   proxy_set_header Host $host:$server_port;
    }

	 


}

webscokst 服务端代码:




import com.hk.frame.dao.model.JyftMessageLogging;
import com.hk.frame.service.IMService;
import com.hk.frame.util.EmojiFilter;
import com.hk.frame.util.JsonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.apache.commons.lang3.StringUtils;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author:wf
 * @Date 2021/5/14 13:55
 * 消息收发
 **/
@Controller
@ServerEndpoint(value = "/websocket/{senderID}")
public class ChatWebSocket {

   /**处理消息的业务类,这个是自己编写的*/
    private static IMService imService;
    @Autowired
    public void setChatService(IMService imService) {
        ChatWebSocket.imService = imService;
    }

    /** 当前在线连接数。应该把它设计成线程安全的 */
    private static  int onlineCount = 0;
    /** 存放每个客户端对应的MyWebSocket对象。实现服务端与单一客户端通信的话,其中Key可以为用户标识 */
    private static ConcurrentHashMap<String, ChatWebSocket> webSocketSet = new ConcurrentHashMap<String, ChatWebSocket>();
    /** 与某个客户端的连接会话,需要通过它来给客户端发送数据 */
    private Session WebSocketsession;
    /** 当前发消息的人员编号 */
    private String senderID = "";


    /**
     * 连接建立成功调用的方法
     * @param param 发送者ID,是由谁发送的
     * @param WebSocketsession 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
     */
    @OnOpen
    public void onOpen(@PathParam(value = "senderID") String param, Session WebSocketsession) {
        System.out.println("人员编号:"+param+":加入聊天");

        //接收到发送消息的人员编号
        senderID = param;
        System.out.println("senderID:"+senderID);
        this.WebSocketsession = WebSocketsession;
        //加入map中,绑定当前用户和socket
        webSocketSet.put(param, this);
        //在线数加1
        addOnlineCount();
    }


    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        if (StringUtils.isNotBlank(senderID)) {
            //从set中删除
            webSocketSet.remove(senderID);
            //在线数减1
            subOnlineCount();
        }
    }


    /**
     * 收到客户端消息后调用的方法
     *
     * @param content 客户端发送过来的消息
     * @param session 可选的参数
     */
    @SuppressWarnings("unused")
    @OnMessage
    public void onMessage(String content, Session session) {
        //给指定的人发消息
        //这里的JsonUtil和JyftMessageLogging都是自己类,目的在于,将数据反序列化成对象
        sendToUser(JsonUtil.fromJson(content,JyftMessageLogging.class),content);
        //群发消息
        //sendAll(message);
    }


    /**
     * 给指定的人发送消息
     *
     * @param chatMsg 消息对象
     */
    public void sendToUser(JyftMessageLogging chatMsg,String msgContent) {
        //获取接收者ID
        String recipientId = chatMsg.getRecipientId();
        //获取消息内容
        String messageContent = chatMsg.getMessageContent();
        try {
            if (webSocketSet.get(recipientId) != null) {
                //这里,我将消息添加至我自己的缓存,避免发送一条存储一条,消耗性能
                imService.setMsgCache(chatMsg);
                webSocketSet.get(recipientId).sendMessage(msgContent);
            }else{
                //设置读取状态为未读
                chatMsg.setReadStatus("0");
                //这里,我将消息添加至我自己的缓存,避免发送一条存储一条,消耗性能
                imService.setMsgCache(chatMsg);
                //用户不在线时先将这条消息存到数据库
                Map<String,Object>  param=new HashMap<>();
                param.put("friendRelationshipID",chatMsg.getFriendRelationshipID());
                imService.addChatLogService(param);
                webSocketSet.get(senderID).sendMessage("0"+"|"+"当前用户不在线");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 给所有人发消息
     *
     * @param message 消息内容
     */
    private void sendAll(String message) {
        String sendMessage = message.split("[|]")[1];
        //遍历HashMap
        for (String key : webSocketSet.keySet()) {
            try {
                //判断接收用户是否是当前发消息的用户
                if (!senderID.equals(key)) {
                    webSocketSet.get(key).sendMessage(sendMessage);
                    System.out.println("key = " + key);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 发生错误时调用
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        error.printStackTrace();
    }


    /**
     * 为指定用户发送消息
     *
     * @param message 消息内容
     * @throws IOException
     */
    public void sendMessage(String message) throws IOException {
        //加同步锁,解决多线程下发送消息异常关闭
        synchronized (this.WebSocketsession){
            this.WebSocketsession.getBasicRemote().sendText(message);
        }
    }

    /**
     * 获取当前在线人数
     * @return 返回当前在线人数
     */
    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    /**
     * 增加当前在线人数
     */
    public static synchronized void addOnlineCount() {
        ChatWebSocket.onlineCount++;
    }

    /**
     * 减少当前在线人数
     */
    public static synchronized void subOnlineCount() {
        ChatWebSocket.onlineCount--;
    }

}

springboot中配置webscoket

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

/**
 * @Author:wf
 * @Date 2021/5/14 13:50
 **/
@Configuration
@EnableWebSocket
public class WebSocketConfig {

    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

前端连接:

//此处的id为用户ID
 wx.connectSocket({
      url: 'wss://xcxapi.wfeifei.com/websocket/' + id,//线上地址
      //如需本地测试,就使用如下配置,注意是ws协议,不是wss,因为小程序要求使用wss,等同于要求使用https是一个道理,所以本地开发需要使用ws,上线后换成wss
      
      //url: `ws://本地IP:本地端口号/websocket/` + id, //本地
      success: function () {
        console.log('websocket连接成功~')
      },
      fail: function () {
        console.log('websocket连接失败~')
      },
    })

自此,就成功了。希望对大家有帮助

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

亿只王菜菜

各位爷,赏口饭吃吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值