web-msg-sender的https支持改造
Posted showker
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了web-msg-sender的https支持改造相关的知识,希望对你有一定的参考价值。
用的是nginx代理转发443到2120端口实现,官方说workman原生支持,没有实现(现象是 访问 htttps://域名:2120/ 超时,不知道是服务器问题还是什么)
后转为用nginx代理转发实现
1、假设用https://socket.test.com 作为socket连接的地址. https://www.test.com还是网站本身,实现共存,不影响主站访问
1、nginx的 网站.conf,注意红色部分。2121那个转发不是必须的,因为是服务端curl请求,可以直接请求ip地址带端口
server listen 443; server_name *.test.com test.com; set $flag 0; if ($host != ‘www.test.com‘) set $flag "$flag1"; if ($host = ‘socket.test.com‘) set $flag "$flag1"; if ($flag = "01") rewrite ^/(.*)$ http://www.test.com/$1 permanent; #if ($host != ‘www.test.com‘ ) # ssl on; ssl_certificate cert/cert-1542176077391__.test.com.crt; ssl_certificate_key cert/cert-1542176077391__.test.com.key; ssl_session_timeout 5m; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; index index.html index.htm index.php default.html default.htm default.php; root /home/wwwroot/test; error_page 404 /404.html; location /push.api proxy_pass http://127.0.0.1:2121; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header X-Real-IP $remote_addr; location /socket.io proxy_pass http://127.0.0.1:2120; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header X-Real-IP $remote_addr; location / if (!-e $request_filename) rewrite ^/(.+\.(html|xml|json|htm|php|jsp|asp|shtml))$ /index.php?$1 last; # Deny access to PHP files in specific directory #location ~ /(wp-content|uploads|wp-includes|images)/.*\.php$ deny all; include enable-php5.2.conf; location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ expires 30d; location ~ .*\.(js|css)?$ expires 12h; location ~ /.well-known allow all; location ~ /\. deny all; #access_log /home/wwwlogs/test.com.log;
2、服务端socket.io.php,无需更改。还是用端口2120,不用开启ssl
<?php use Workerman\Worker; use Workerman\WebServer; use Workerman\Lib\Timer; use PHPSocketIO\SocketIO; include __DIR__ . ‘/vendor/autoload.php‘; // 全局数组保存uid在线数据 $uidConnectionMap = array(); // 记录最后一次广播的在线用户数 $last_online_count = 0; // 记录最后一次广播的在线页面数 $last_online_page_count = 0; // PHPSocketIO服务 $sender_io = new SocketIO(2120); // 客户端发起连接事件时,设置连接socket的各种事件回调 $sender_io->on(‘connection‘, function($socket) file_put_contents(‘/home/wwwroot/test/home/socketioserver.txt‘,date(‘Y-m-d H:i:s‘)."\r\n connection:uid:".$uid."\r\n=======\r\n",FILE_APPEND); /**/ // error_reporting(E_ALL ^ E_NOTICE); //$root_dir = realpath(dirname(__FILE__).‘/../‘); //require_once($root_dir."/config/config.php"); /* require_once(APP_DIR.‘/base/kernel.php‘); @require_once(APP_DIR.‘/base/defined.php‘); if(!kernel::register_autoload()) require_once(APP_DIR.‘/base/autoload.php‘); */ /**/ // 当客户端发来登录事件时触发 $socket->on(‘login‘, function ($uid)use($socket) file_put_contents(‘/home/wwwroot/test/home/socketioserver.txt‘,date(‘Y-m-d H:i:s‘)."\r\n login:uid:".$uid."\r\n=======\r\n",FILE_APPEND); global $uidConnectionMap, $last_online_count, $last_online_page_count; // 已经登录过了 if(isset($socket->uid)) return; // 更新对应uid的在线数据 $uid = (string)$uid; if(!isset($uidConnectionMap[$uid])) $uidConnectionMap[$uid] = 0; // 这个uid有++$uidConnectionMap[$uid]个socket连接 ++$uidConnectionMap[$uid]; /* $dbs= kernel::database(); $dbs->exec(‘update sdb_b2c_online_users set online="‘.serialize($uidConnectionMap).‘"‘);*/ //file_put_contents(HOME_DIR.‘/chat/OnlineUsersCache.txt‘,serialize($uidConnectionMap)); //app::get(‘b2c‘)->setConf(‘chat.online_users‘,$uidConnectionMap); // 将这个连接加入到uid分组,方便针对uid推送数据 $socket->join($uid); $socket->uid = $uid; // 更新这个socket对应页面的在线数据 $socket->emit(‘update_online_count‘,count($uidConnectionMap)); ); // 当客户端断开连接是触发(一般是关闭网页或者跳转刷新导致) $socket->on(‘disconnect‘, function () use($socket) file_put_contents(‘/home/wwwroot/test/home/socketioserver.txt‘,date(‘Y-m-d H:i:s‘)."\r\n disconnect:uid:".$socket->uid."\r\n=======\r\n",FILE_APPEND); if(!isset($socket->uid)) return; global $uidConnectionMap, $sender_io; // 将uid的在线socket数减一 if(--$uidConnectionMap[$socket->uid] <= 0) unset($uidConnectionMap[$socket->uid]); // file_put_contents(HOME_DIR.‘/chat/OnlineUsersCache.txt‘,serialize($uidConnectionMap)); ); ); // 当$sender_io启动后监听一个http端口,通过这个端口可以给任意uid或者所有uid推送数据 $sender_io->on(‘workerStart‘, function() // 监听一个http端口 $inner_http_worker = new Worker(‘http://0.0.0.0:2121‘); // 当http客户端发来数据时触发 $inner_http_worker->onMessage = function($http_connection, $data) $_POST = $_POST ? $_POST : $_GET; if($_POST[‘appkey‘]!=‘fads‘) // return $http_connection->send(‘fail‘); // 推送数据的url格式 type=publish&to=uid&content=xxxx switch(@$_POST[‘type‘]) //聊天 case ‘publish‘: global $sender_io; $to = @$_POST[‘to‘]; $_POST[‘content‘] = (@$_POST[‘content‘]); // 有指定uid则向uid所在socket组发送数据 if($to) $sender_io->to($to)->emit(‘new_msg‘, $_POST[‘content‘]); // 否则向所有uid推送数据 else $sender_io->emit(‘new_msg‘, @$_POST[‘content‘]); // http接口返回ok return $http_connection->send(‘ok‘); break; //新的拍卖出价时 case ‘new_auction_price‘: global $sender_io; $to = @$_POST[‘to‘]; $_POST[‘content‘] = (@$_POST[‘content‘]); // 有指定uid则向uid所在socket组发送数据 if($to) $sender_io->to($to)->emit(‘new_auction‘, $_POST[‘content‘]); // 否则向所有uid推送数据 else $sender_io->emit(‘new_auction_price‘, @$_POST[‘content‘]); return $http_connection->send(‘ok‘); break; //创建拍卖 case ‘create_auction‘: global $sender_io; $to = @$_POST[‘to‘]; // 有指定uid则向uid所在socket组发送数据 if($to) $sender_io->to($to)->emit(‘create_auction‘, $_POST[‘content‘]); // 否则向所有uid推送数据 else $sender_io->emit(‘create_auction‘, @$_POST[‘content‘]); return $http_connection->send(‘ok‘); break; //延迟 case ‘delay_auction‘: global $sender_io; $to = @$_POST[‘to‘]; // 有指定uid则向uid所在socket组发送数据 if($to) $sender_io->to($to)->emit(‘delay_auction‘, $_POST[‘content‘]); // 否则向所有uid推送数据 else $sender_io->emit(‘delay_auction‘, @$_POST[‘content‘]); return $http_connection->send(‘ok‘); break; //流拍 case ‘cancel_auction‘: global $sender_io; $to = @$_POST[‘to‘]; // 有指定uid则向uid所在socket组发送数据 if($to) $sender_io->to($to)->emit(‘cancel_auction‘, $_POST[‘content‘]); // 否则向所有uid推送数据 else $sender_io->emit(‘cancel_auction‘, @$_POST[‘content‘]); return $http_connection->send(‘ok‘); break; //开始今日拍卖时+切换到下一个拍卖时+结束当日拍卖到下一个拍卖时 case ‘change_domain_item‘: global $sender_io; $to = @$_POST[‘to‘]; // 有指定uid则向uid所在socket组发送数据 if($to) $sender_io->to($to)->emit(‘change_domain_item‘, $_POST[‘content‘]); // 否则向所有uid推送数据 else $sender_io->emit(‘change_domain_item‘, @$_POST[‘content‘]); return $http_connection->send(‘ok‘); return $http_connection->send(‘fail‘); ; // 执行监听 $inner_http_worker->listen(); // 一个定时器,定时向所有uid推送当前uid在线数及在线页面数 Timer::add(1, function() global $uidConnectionMap, $sender_io, $last_online_count, $last_online_page_count; $online_count_now = count($uidConnectionMap); $online_page_count_now = array_sum($uidConnectionMap); // 只有在客户端在线数变化了才广播,减少不必要的客户端通讯 if($last_online_count != $online_count_now || $last_online_page_count != $online_page_count_now) $sender_io->emit(‘update_online_count‘, $online_count_now); $last_online_count = $online_count_now; $last_online_page_count = $online_page_count_now; ); ); if(!defined(‘GLOBAL_START‘)) Worker::runAll();
3、客户端js.最大的坑就是这里。原先以为io(‘地址‘),是要填完整的,比如下面
<script src=‘https://socket.test.com/web-msg-sender-master/socket.io-client/socket.io.js?v=123123‘></script>
<script>
$(document).ready(function ()
// 创建WebSocket 对象
var socket = io("https://socket.test.com/socket.io",debug:true);
/*
* 2019-08-24 11:27:35
connection:uid:
=======
2019-08-24 11:28:04
disconnect:uid:
*
* */
//var socket = io("http://118.190.21.61:2120",debug:true);
/*
* 2019-08-24 11:26:08
connection:uid:
=======
2019-08-24 11:26:08
login:uid:1566617168000
=======
2019-08-24 11:26:35
disconnect:uid:1566617168000
=======
* */
//连接成功时,触发事件
// 连接后登录
console.log(‘socket‘,socket);
socket.on(‘connect‘, function()
socket.emit(‘login‘, uid);
);
// 后端推送来消息时
socket.on(‘new_msg‘, function(msg)
$(‘#content‘).html(‘收到消息:‘+msg);
$(‘.notification.sticky‘).notify();
);
// 后端推送来在线数据时
socket.on(‘update_online_count‘, function(online_stat)
$(‘#online_box‘).html(online_stat);
);
)
</script>
后来发现怎么也连不上socket服务,on事件监听完全失效。
后来看了 lib/manager.js里源码才知道,系统会自动补全socket.io,所以初始化时io里变量只需填写域名即可,正确如下。注意红色加粗部分
<script src=‘https://socket.test.com/web-msg-sender-master/socket.io-client/socket.io.js?v=123123‘></script> <script> $(document).ready(function () // 创建WebSocket 对象 var socket = io("https://socket.test.com",debug:true); /* * 2019-08-24 11:27:35 connection:uid: ======= 2019-08-24 11:28:04 disconnect:uid: * * */ //var socket = io("http://118.190.21.61:2120",debug:true); /* * 2019-08-24 11:26:08 connection:uid: ======= 2019-08-24 11:26:08 login:uid:1566617168000 ======= 2019-08-24 11:26:35 disconnect:uid:1566617168000 ======= * */ //连接成功时,触发事件 // 连接后登录 console.log(‘socket‘,socket); socket.on(‘connect‘, function() socket.emit(‘login‘, uid); ); // 后端推送来消息时 socket.on(‘new_msg‘, function(msg) $(‘#content‘).html(‘收到消息:‘+msg); $(‘.notification.sticky‘).notify(); ); // 后端推送来在线数据时 socket.on(‘update_online_count‘, function(online_stat) $(‘#online_box‘).html(online_stat); ); ) </script>
以上是关于web-msg-sender的https支持改造的主要内容,如果未能解决你的问题,请参考以下文章
HTTPS改造全过程_2018年百度将扶持HTTPS站点!!!
机械革命黑苹果改造计划第四番-外接显示器win时间不正确问题解决