前端代码及模块
var socketManager = api.require('socketManager');
socketManager.createSocket({
host: '192.168.1.140',
port: 8283
}, function(ret, err) {
if (ret) {
if( ret.data == "success" ) {
return ;
}
console.log(JSON.stringify(ret));
var data = $api.strToJson(ret.data);
// var data = eval('('+ret.data+')');
if( data.cliend ){
$api.text($api.dom(".flex-1"),data.cliend) ;
}
// if(ret.data == 'success'){
// return ;
// }
// var data = eval('('+ret.data+')');
// console.log( data );
// socketManager.write({
// sid: ret.sid,
// data: '你好'
// }, function(ret, err) {
// if (ret.status) {
// console.log(JSON.stringify(ret));
// } else {
// console.log(JSON.stringify(err));
// }
// });
// socketManager.closeSocket({
// sid: ret.sid
// }, function(ret, err) {
// if (ret.status) {
// alert(JSON.stringify(ret));
// } else {
// alert(JSON.stringify(err));
// }
// });
} else {
console.log(JSON.stringify(err));
}
});
后端代码及项目录:
我使用的是 gateway-worker (原理都是一样的)
composer require workerman/gateway-worker-for-win
这个是主要的目录
对应的代码:
start_for_win.bat
php run\start_register.php run\start_gateway.php run\start_businessworker.php
pause
const.php
<?php
/**
* Created by PhpStorm.
* User: huizi
* Date: 2019/5/22
* Time: 14:42
*/
// 注册协议
define('GW_REGISTER_PROTOCOL','0.0.0.0:1236');
// 注册地址
define('GW_REGISTER_ADDRESS','127.0.0.1:1236');
// 网关地址
define('GW_GATEWAY_ADDRESS','0.0.0.0:8283');
// 网关起始端口
define('GW_GATEWAY_START_PORT','2900');
// 心跳检测间隔,单位:秒,0 表示不发送心跳检测
define('GW_GATEWAY_PING_INTERVAL',10);
// 本机ip,分布式部署时请设置成内网ip(非127.0.0.1)
define('GW_LOCAL_HOST_IP','127.0.0.1');
// 网关名称
define('GW_GATEWAY_NAME','Gateway001');
// worker进程名称
define('GW_WORKER_NAME','BusinessWorker001');
// Gateway进程数量,建议与CPU核数相同
define('GW_GATEWAY_COUNT',2);
// BusinessWorker进程数量,建议设置为CPU核数的1倍-3倍
define('GW_BUSINESS_WORKER_COUNT',6);
// Business业务处理类,可以带命名空间
define('GW_BUSINESS_EVENT_HANDLER','app\gatewayapp\controller\GwEvents');
start_businessworker.php
<?php
/**
* Created by PhpStorm.
* User: huizi
* Date: 2019/5/22
* Time: 14:41
*/
use Workerman\Worker;
use GatewayWorker\BusinessWorker;
use Workerman\Autoloader;
$businessInstance = new GwBusinessWorker();
call_user_func_array(array($businessInstance,'index'),array());
class GwBusinessWorker {
public function __construct() {
require_once dirname(__FILE__) . '/../../../vendor/autoload.php';
include_once dirname(__FILE__).'/../const.php';
}
public function index() {
// bussinessWorker 进程
$worker = new BusinessWorker();
// worker名称
$worker->name = GW_WORKER_NAME;
// bussinessWorker进程数量
$worker->count = GW_BUSINESS_WORKER_COUNT;
// 服务注册地址
$worker->registerAddress = GW_REGISTER_ADDRESS;
//设置处理业务的类,此处制定Events的命名空间
$worker->eventHandler = GW_BUSINESS_EVENT_HANDLER;
// 如果不是在根目录启动,则运行runAll方法
if(!defined('GLOBAL_START')) {
Worker::runAll();
}
}
}
start_gateway.php
<?php
/**
* Created by PhpStorm.
* User: huizi
* Date: 2019/5/22
* Time: 14:41
*/
use Workerman\Worker;
use GatewayWorker\Gateway;
use Workerman\Autoloader;
$gatewayInstance = new GwGateway();
call_user_func_array(array($gatewayInstance,'index'),array());
class GwGateway {
private $gatewayAddress;
public function __construct() {
require_once dirname(__FILE__) . '/../../../vendor/autoload.php';
include_once dirname(__FILE__).'/../const.php';
// gateway 进程,这里使用websocket协议
$this->gatewayAddress = sprintf('tcp://%s',GW_GATEWAY_ADDRESS);
}
public function index() {
$gateway = new Gateway($this->gatewayAddress);
// 设置名称,方便status时查看
$gateway->name = GW_GATEWAY_NAME;
// 设置进程数,gateway进程数建议与cpu核数相同
$gateway->count = GW_GATEWAY_COUNT;
// 本机ip,分布式部署时请设置成内网ip(非127.0.0.1)
$gateway->lanIp = GW_LOCAL_HOST_IP;
// 内部通讯起始端口,假如$gateway->count=4,起始端口为4000
// 则一般会使用4000 4001 4002 4003 4个端口作为内部通讯端口
$gateway->startPort = GW_GATEWAY_START_PORT;
// 服务注册地址
$gateway->registerAddress = GW_REGISTER_ADDRESS;
// 心跳间隔,单位:秒,0 表示不发送心跳检测
$gateway->pingInterval = GW_GATEWAY_PING_INTERVAL;
// 心跳数据
$gateway->pingData = json_encode([
"type" => "ping"
]);
/*
// 当客户端连接上来时,设置连接的onWebSocketConnect,即在websocket握手时的回调
$gateway->onConnect = function($connection) {
$connection->onWebSocketConnect = function($connection , $http_header) {
// 可以在这里判断连接来源是否合法,不合法就关掉连接
// $_SERVER['HTTP_ORIGIN']标识来自哪个站点的页面发起的websocket链接
if($_SERVER['HTTP_ORIGIN'] != 'http://kedou.workerman.net') {
$connection->close();
}
// onWebSocketConnect 里面$_GET $_SERVER是可用的
// var_dump($_GET, $_SERVER);
};
};
*/
// 如果不是在根目录启动,则运行runAll方法
if(!defined('GLOBAL_START')) {
Worker::runAll();
}
}
}
start_register.php
<?php
/**
* Created by PhpStorm.
* User: huizi
* Date: 2019/5/22
* Time: 14:40
*/
use GatewayWorker\Register;
use Workerman\Worker;
$registerInstance = new GwRegister();
call_user_func_array(array($registerInstance, 'index'), array());
class GwRegister
{
public function __construct()
{
require_once dirname(__FILE__) . '/../../../vendor/autoload.php';
include_once dirname(__FILE__) . '/../const.php';
}
public function index()
{
// register 必须是text协议
$registerAddress = sprintf('text://%s', GW_REGISTER_PROTOCOL);
$register = new Register($registerAddress);
// 如果不是在根目录启动,则运行runAll方法
if (!defined('GLOBAL_START')) {
Worker::runAll();
}
}
}
GwEvents.php
<?php
/**
* Created by PhpStorm.
* User: huizi
* Date: 2019/5/22
* Time: 14:38
*/
namespace app\gatewayapp\controller;
use GatewayWorker\Lib\Gateway;
class GwEvents
{
/**
* 当客户端连接时触发
* 如果业务不需此回调可以删除onConnect *
* @param int $client_id 连接id
*/
public static function onConnect($client_id)
{
// 向当前client_id发送数据
// Gateway::sendToClient($client_id, sprintf('Hello %s',$client_id));
Gateway::sendToClient($client_id, json_encode([
'type' => 1,
'client_id' => $client_id,
'msg' => sprintf('Hello %s', $client_id)
]));
// 向所有人发送
// Gateway::sendToAll(sprintf('用户 %s 已登录!',$client_id));
}
/**
* 当客户端发来消息时触发
* @param int $client_id 连接id
* @param mixed $message 具体消息
*/
public static function onMessage($client_id, $message)
{
// 向所有人发送
Gateway::sendToAll(json_encode([
'type' => 1,
'client_id' => $client_id,
'msg' => sprintf('用户 %s 说:%s', $client_id, $message)
]));
}
/**
* 当用户断开连接时触发
* @param int $client_id 连接id
*/
public static function onClose($client_id)
{
// 向所有人发送
GateWay::sendToAll(sprintf('用户 %s 已退出!', $client_id));
}
}
Index.php
<?php
/**
* Created by PhpStorm.
* User: huizi
* Date: 2019/5/22
* Time: 14:39
*/
namespace app\gatewayapp\controller;
use GatewayWorker\Lib\Gateway;
use think\Controller;
class Index extends Controller
{
public function index() {
return $this->fetch();
}
public function sendMessage(){
$msg = [
'type' => 1 ,
'msg' => 'oj',
'cliend' => "这是一个实时的手法消息的复方"
];
Gateway::sendToAll( json_encode($msg) );
}
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebSocket示例</title>
</head>
<body>
<button onclick="sendMessage()">发信息</button>
<script src="/static/jquery-3.3.1/jquery-3.3.1.min.js">
</script>
<script type="text/javascript">
// var webSocket = null;
//
// initSocket();
//
// function initSocket() {
// if (!"WebSocket" in window) {
// console.log("您的浏览器不支持 WebSocket!");
// return;
// }
// webSocket = new WebSocket("ws://"+document.domain+":8283");
// webSocket.onopen = handleSend;
// webSocket.onmessage = handleMessage;
// webSocket.onclose = handleClose;
// webSocket.onerror = handleError;
// }
//
// // 向服务器端发送数据
// function handleSend() {
// // Web Socket 已连接上,使用 send() 方法发送数据
// testing();
// }
//
// // 处理服务器端发送过来的数据
// function handleMessage(evt) {
// var received_msg = evt.data;
// console.log(received_msg);
// }
//
// // 处理连接关闭事件
// function handleClose() {
// console.log("连接已关闭...");
// }
//
// // 处理WebSocket错误
// function handleError() {
// console.log("WebSocketError!");
// }
//
// function testing() {
// //每隔3秒钟向服务器发送数据,此处仅用于测试
// var items = ['张三','李四','小二黑','阿杜','单工','大理寺','花荣','刘备','诸葛亮'];
// setInterval(function () {
// var item = items[Math.floor(Math.random()*items.length)];
// webSocket.send(item);
// },3000);
// }
function sendMessage() {
$.post("{:url('gatewayapp/index/sendMessage')}",{},function (res) {
console.log(res);
},"json");
}
</script>
</body>
</html>
具体的 上传到github https://github.com/wang119c/msg_gateway.git