WSS服务端接入过程记录

        公司游戏需要搞个微信小程序版,然后小程序需要用wss协议,即webSocket+ssl,所以记录一下(踩坑的)过程,方便看到这篇文章的人(虽然已经是超过半年以前的事情,实际上老大来问我的时候已经快忘光了,找点时间记录下来免得下次继续忘)

目录

一、C++实现webSocket升级

二、ssl实现(通过nginx代理)


一、C++实现webSocket升级

        首先,webSocket是什么?其实就是一个协议,要求数据按照这个协议的规则来进行发放。关于ws的东西网上一搜一大把,这里就不再赘述,有兴趣的可以自己去看一下,这里推荐http - WebSocket 详解 - 不挑食的程序员 - SegmentFault 思否https://segmentfault.com/a/1190000012948613

写得很详细

        然后这里有大佬造的简易轮子,可惜没用上(76条消息) C++实现WebSocket功能及WebSocket协议详解(附代码)_c websocket_贝松的博客-CSDN博客https://blog.csdn.net/qq_39540028/article/details/104493049

        首先,相信看这篇文章的都是有升级wss协议需求的,而不是从头开始构建链接,所以就不说那些了,直接从ws开始。ws其实就握手保证一下链接真实可靠,然后通过这个链接双方互相传输消息,最后交换完消息就挥手关掉链接。具体是怎么实现的呢?

        首先,在http的基础下,客户端会向服务端提出升级协议,这时候是明文请求的

GET / HTTP/1.1
Host: localhost:8080
Origin: http://127.0.0.1:3000
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: w4v7O6xFTi36lq3RNcgctw==

        实际上这里要关心的是两个点,一个是开头的GET,一个是最后的Sec-WebSocket-Key。因为对我实际做的项目来说,需求是能支持同一个服务器接收来自不同客户端的消息,也就是说支持小程序和普通app的混服,而我们自己本身是用的自用协议,所以在客户端开始握手的时候要判断到底是来自于哪里的消息、接下来采用哪种协议去进行通讯。于是乎就直接判断握手消息是否GET开头,是的话后面开始走WS逻辑,否则走我们原来的自用协议。当然假如你有严格要求,或者怕和正在使用的其他协议发生混淆,全部消息检查一遍也是没问题的,上面是ws的 RFC2616的规定,没啥好说的。

        而Sec-WebSocket-Key,这是客户端要求服务端做的一个验证,需要在这串东西后面拼接上258EAFA5-E914-47DA-95CA-C5AB0DC85B11这样一个协议约定的字符串,然后把拼接好的内容先sha1算出来一个哈希值,然后将这个哈希值转成base64字符串,到时候回包能用到。这么做主要是为了向客户端保证自己的确收到了这样一个消息,并且针对这个消息做出回复,保证双方不会被偶然链接影响。

        好了,收到客户端ws的请求,现在要回复了。

HTTP/1.1 101 Switching Protocols
Connection:Upgrade
Upgrade: websocket
Sec-WebSocket-Accept: Oy4NRAQ13jhfONC7bP8dTKb4PTU=

        除了Accept以外的东西实际使用没啥好关心的,照样发出去就行了。

二、ssl实现(通过nginx代理)

        nginx代理其实就是用nginx中转,让前端只向nginx对外端口发消息,nginx处理之后将数据按指定规则发给后端,这里的处理其实也可以包括ssl握手与加密,将前端发过来的WSS处理成WS包,后端只要专心解WS包就好了。

        SSL需要一个证书支持,所谓的证书其实就是一个身份证证明你是你自己。假如是用阿里云之类的服务器的,去申请一个自己对应域名的证书就好了,关于证书的部分可以跳过。但是假如是自机测试调试的话,就需要自己弄一个证书给nginx了。

        首先要注意一点,wss访问是访问域名的,而证书也是对域名进行认证的。自己本机上调试的怎么办?改个host自己弄个域名就好。C:\Windows\System32\drivers\etc这个路径,或者你是linux的话就etc/hosts,加个

127.0.0.1       test.game.net

将test.game.net定向到本机ip上,当然你自己改个域名也行,不过下面的步骤都要自己跟着改。

        域名弄好之后,下个openssl证书开搞,具体可以查看(88条消息) 关于Nginx配置SSL证书(Https)和WebSocket的wss_wss证书_Shiro to kuro的博客-CSDN博客

        记得两个点:

        1.nginx域名填刚刚host里面改的域名

        2.做证书的时候Common Name一定要填那个域名!

        给一下我的conf


#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       80;
        server_name  test.game.net;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

	map $http_upgrade $connection_upgrade { 
		default upgrade; 
		'' close; 
	} 


    # HTTPS server
    #
    server {
        listen       443 ssl;
        server_name  test.game.net;
		
        ssl_certificate      ../keys/server.pem;
        ssl_certificate_key  ../keys/server.key;

       ssl_session_timeout 5m;
		ssl_session_cache shared:SSL:10m;
		ssl_protocols TLSv1 TLSv1.1 TLSv1.2 SSLv2 SSLv3;
		ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
		ssl_prefer_server_ciphers on;
		ssl_verify_client off;

        #location / {
        #    root   html;
        #    index  index.html index.htm;
        #}
		location /{
		  proxy_redirect off;
		  proxy_pass http://本机IP:想要转发的端口/;
		  proxy_set_header Host $host;
		  proxy_set_header X-Real_IP $remote_addr;
		  proxy_set_header X-Forwarded-For $remote_addr:$remote_port;
		  proxy_http_version 1.1;
		  proxy_set_header Upgrade $http_upgrade;
		  proxy_set_header Connection upgrade;
		}
	}
}

        上面最重要的是HTTPS的部分,内容其实就是监听443接口,认为传入的是ssl加密后信息,转发到你自己ip和端口上,然后让你自己的服务端去监听这个端口。

        nginx搭起来了,就可以用在线工具测一下了

        WebSocket在线测试工具 (wstool.js.org)

        只不过浏览器搞的话,因为你的证书是自己当CA签的,浏览器不会认,要先让浏览器放行你的证书。具体操作方法就是开了nginx之后,浏览器上一下监听的域名,然后应该会说网站证书不安全之类的,点一下把你的自签证书加入可信。不然的话用上面的在线工具会报错

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值