基於Web實現遠程與硬件交互

基於Web實現遠程與硬件交互

項目背景:

最近在作一個相似「速遞櫃」的項目,項目需求大概以下:
1.用戶使用微信掃描二維碼
2.後臺匹配相關數據,並存儲用戶信息,最終返回給用戶當前櫃子當前狀態
3.用戶選擇「開櫃」指令,進行存取物品php

需求分析

1.實現跟硬件進行數據交互,使用TCP/IP 長鏈接,意味着,咱們要有一個TCP服務器,TCP服務器一方面接受用戶發過來的相關請求指令,另外一方面完成發送指令給指定硬件這一操做。
2.除了TCP 服務器咱們還須要一個 Websocket 服務器,也有兩個功能,一方面接受客戶端發送的指令,另外一方面處理轉發用戶指令給TCP服務器。sql

功能實現

TCP 服務器,Websocket 服務器 使用相對成熟的 Workman 實現。數據庫

Workerman是一款純PHP開發的開源高性能的PHP socket 服務器框架。被普遍的用於手機app、移動通信,微信小程序,手遊服務端、網絡遊戲、PHP聊天室、硬件通信、智能家居、車聯網、物聯網等領域的開發。 支持TCP長鏈接,支持Websocket、HTTP等協議,支持自定義協議。擁有異步Mysql、異步Redis、異步Http、異步消息隊列等衆多高性能組件。

GatewayWorker 目錄結構

├── Applications // 這裏是全部開發者應用項目
│   └── YourApp  // 其中一個項目目錄,目錄名能夠自定義
│       ├── Events.php // 開發者只須要關注這個文件
│       ├── start_gateway.php // gateway進程啓動腳本,包括端口號等設置
│       ├── start_businessworker.php // businessWorker進程啓動腳本
│       └── start_register.php // 註冊服務啓動腳本
│
├── start.php // 全局啓動腳本,此腳本會依次加載Applications/項目/start_*.php啓動腳本
│
└── vendor    // GatewayWorker框架和Workerman框架源碼目錄,此目錄開發者不用關心
  1. 首先咱們 Applications 複製兩份 YourApp 目錄下的文件,此時咱們的目錄結構應該是這樣的
├── Applications // 這裏是全部開發者應用項目
│   └── TcpServer  // 其中一個項目目錄,目錄名能夠自定義
│       ├── Events.php // 開發者只須要關注這個文件
│       ├── start_gateway.php // gateway進程啓動腳本,包括端口號等設置
│       ├── start_businessworker.php // businessWorker進程啓動腳本
│       └── start_register.php // 註冊服務啓動腳本
│   └── WSServer  
│       ├── Events.php 
│       ├── start_gateway.php 
│       ├── start_businessworker.php 
│       └── start_register.php 
│
├── start.php // 全局啓動腳本,此腳本會依次加載Applications/項目/start_*.php啓動腳本
│
└── vendor    // GatewayWorker框架和Workerman框架源碼目錄,此目錄開發者不用關心
  1. 修改以及配置 TCPServerstart_register.php 下咱們不作任何修改,但須要注意的是register 必須是text協議
// register 必須是text協議
$register = new Register('text://0.0.0.0:1238');

2.修改 start_gateway.php小程序

// gateway 進程,這裏使用 TCP 協議,能夠用telnet測試
$gateway = new Gateway("tcp://0.0.0.0:8282");
// gateway名稱,status方便查看
$gateway->name = 'TcpGateway';
// gateway進程數
$gateway->count = 4;
// 本機ip,分佈式部署時使用內網ip
$gateway->lanIp = '127.0.0.1';
// 內部通信起始端口,假如$gateway->count=4,起始端口爲4000
// 則通常會使用4000 4001 4002 4003 4個端口做爲內部通信端口 
$gateway->startPort = 2900;
// 服務註冊地址
$gateway->registerAddress = '127.0.0.1:1238';

3.修改 start_businessworker.php微信小程序

// bussinessWorker 進程
$worker = new BusinessWorker();
// worker名稱
$worker->name = 'TcpBusinessWorker';
// bussinessWorker進程數量
$worker->count = 4;
// 服務註冊地址
$worker->registerAddress = '127.0.0.1:1238';

4.根據上面的操做,咱們修改WSServer目錄下的文件,這個修改跟上面同樣的,可是要注意的是,兩個應用應該是不用的端口,因此須要修改的地方有兩個,start_gateway下的端口,還有start_register端口。!!!! 兩個應用下register 和 Gateway 端口必定不一致!!!服務器

好了,到目前爲止,咱們已經完成了兩個服務器的建立,那麼咱們兩個服務器之間如何數據共享呢?答案很簡單,咱們在ws服務下建立一個tcp 客戶端便可,讓tcp 客戶端與咱們tcp 服務器鏈接就能夠,而後經過tcp 客戶端直接發送相關數據給tcp服務器就能夠,固然並非全部數據都是經過這樣的方式共享的,咱們其餘信息仍是經過共用一個數據庫來共享的。相關代碼以下:微信

public static function onConnect($client_id)
    {
        // 向全部人發送
        $host = "127.0.0.1";
        $port = 8282;
        global $socket;
        if (empty($socket)) {
            $socket = TcpClient::getInstace()->connect($host, $port);
        Gateway::sendToClient($client_id, "$client_id welcome\n\r");
        }
    }


    public static function onMessage($client_id, $message)
    {
        if ($GLOBALS['socket']) {
            // 數據指令解包
            $message_arr = str_split(str_replace(' ', '', trim($message)), 2);
            $cmd=null;
            for ($j = 0; $j < count($message_arr); $j++) {
                //socket_write($GLOBALS['socket'], bin2hex($message_arr[$j]));
                socket_write($GLOBALS['socket'],chr(hexdec($message_arr[$j])));
            }
        }
    }

好了,截止目前咱們就完成了服務端工做,固然客戶端只是簡單的建立一個ws鏈接就好。網絡

相關文章
相關標籤/搜索