远程串口不是梦

5 篇文章 0 订阅
4 篇文章 0 订阅
<?php
use Workerman\Worker;
require_once __DIR__ . '/../../vendor/autoload.php';
class mqtt
{
    protected $_worker = null;
    public function __construct($ip = '0.0.0.0', $port = 2206)
    {
        $worker = new Worker("tcp://$ip:$port");
        $worker->count = 1;
        $worker->name = 'ChannelServer';
        $worker->channels = array();
        $worker->onMessage = array($this, 'onMessage') ;
        $worker->onClose = array($this, 'onClose'); 
        $this->_worker = $worker;
    }
    public function onClose($connection)
    {
        if(empty($connection->channels))
        {
            return;
        }
        foreach($connection->channels as $channel)
        {
            unset($this->_worker->channels[$channel][$connection->id]);
            if(empty($this->_worker->channels[$channel]))
            {
                unset($this->_worker->channels[$channel]);
            }
        }
    }
    public function onMessage($connection, $data)
    {
        echo $data."\r\n";
		if(!$data)
        {
            return;
        }
        $worker = $this->_worker;
        $msg=json_decode($data, true);
		if(isset($msg['type']) && isset($msg['channels']))
		{
			$type = $msg['type'];
			$channel = $msg['channels'];
		}
		else
		{
			$type=null;
		}
        switch($type)
        {
            case 'subscribe'://订阅
                $connection->channels[$channel] = $channel;
                $worker->channels[$channel][$connection->id] = $connection;
				$connection->send("OK\r\n");
                break;
            case 'unsubscribe':
                if(isset($connection->channels[$channel]))
                {
                    unset($connection->channels[$channel]);
                }
                if(isset($worker->channels[$channel][$connection->id]))
                {
                    unset($worker->channels[$channel][$connection->id]);
                    if(empty($worker->channels[$channel]))
                    {
                        unset($worker->channels[$channel]);
                    }
                }
				$connection->send("OK\r\n");
                break;
			default:
				if(empty($connection->channels))
				{
					$connection-send("goal is null\r\n");
					return;
				}
				foreach($connection->channels as $channel)
				{
					foreach($worker->channels[$channel] as $connection_t)
					{
						if($connection_t != $connection)
						{
							//echo $data;
							$connection_t->send($data);
						}

					}
				}
			
			break;
        }
    }
}
$channel_server = new mqtt("0.0.0.0",12060);
Worker::runAll();

以上是服务器代码,不到100行。

现场调试,现场工作人员需要通过485,或者232 ttl连接设备然后打开电脑,远程桌面操作设备,不太友好。我这里有个想法,workerman搭建channel,类似mqtt,几句代码就搞定,简单,然后设备端使用esp8266,esp32,w600,nb,2g,4g,设备几句代码连接workerman,然后随便搞一个网络调试助手,订阅设备消息,设备通过通信模块的数据到网络调试助手那里来了,网络调试发布消息,设备端就能接受到,然后转发给设备,过滤掉不需要的信息,即可。

设备端代码

-- LuaTools需要PROJECT和VERSION这两个信息
PROJECT = "socket2demo"
VERSION = "1.0.0"
-- 引入必要的库文件(lua编写), 内部库不需要require
local sys = require "sys"
log.info("main", "socket demo, tcp long connect")
log.info("mac", wlan.get_mac())
wlan.connect("CMCC-PXW", "2011013837") -- wifi信息在这里, 如果想用airkiss, 看app/playit/main.lua
sys.subscribe("WLAN_READY", function ()
    print("!!! wlan ready event !!! send ntp")
    socket.ntpSync()
end)
local PB7 = 27
gpio.setup(PB7, function(msg) log.info("IQR", "PB7/27", msg) end)
local cacheData1 = ""
uart.on(1,"receive",function(id, len)
	local s1 = uart.read(id,1024)--
	if s1 then cacheData1 = cacheData1..s1 end
	sys.timerStart(function() sys.publish("UART1_RECEIVE")end, 20)
 end)
-- 向串口发送收到的字符串
--local numID
local function procU1()
	sys.publish("NET_WRITE",cacheData1,"uart1")--异步
	cacheData1 = ""
end
sys.subscribe("UART1_RECEIVE",procU1)
uart.setup(1, 115200)
sys.subscribe("UART_WRITE", function(id, data)
    if data and #data > 0 then
        uart.write(id, data)
    end
end)
sys.taskInit(function()
    -- 等待联网成功
    sys.waitUntil("WLAN_READY", 30000)
    while 1 do
        log.info("main", "socket loop")
        if wlan.ready() then
            collectgarbage("collect")
            collectgarbage("collect")
            local s = socket.tcp()
            s:host("192.168.1.15") -- 改成服务器ip或者域名
            s:port(12060) -- 改成服务器端口
            s:on("connect", function(id, re)
                -- 连接成功后, 发注册包 {mac:"AABBCCDDEEFF"}
                log.info("netc", "connect result", re)
                if re then
				----------------------------------------
                    local jdata = json.encode({type="subscribe",channels=wlan.get_mac(),mac=wlan.get_mac()})
                    s:send(jdata)
                end
            end)

            s:on("recv", function(id, re)
                print("recv", id, #re, re)
                if re then
					sys.publish("UART_WRITE", 1, re)
					-- local msg = json.decode(re)
					-- if msg.msg~=nil then
						-- sys.publish("UART_WRITE", 1, msg.msg)
					-- end
                end
            end)
            if s:start() == 0 then
                -- 启动成功后, 连接中断时必然有NETC_END_XX事件
                -- 因为是长连接, 就这样等着就差不多了
                local topic = "NETC_END_" .. s:id()
				while s:closed() == 0 do
					local result, data = sys.waitUntil({topic, "NET_WRITE"}, 30000)
	                if result then
                        if data ~= nil and type(data) == "string" then
                            s:send(data)
							--local jdata = json.encode({type="publish",channels=wlan.get_mac(),msg=data})
							--s:send(jdata)
                        end
                    else 
						log.info("s", "heartbeat ping")
                        s:send("ping")
                    end					
                end
            else
                log.info("netc", "netc start fail!!")
            end
            -- 一定要清理好, 不然内存泄漏, 模块内存少啊!!!
            s:clean()
            collectgarbage("collect")
            collectgarbage("collect")
            --sys_memdump()
            sys.wait(2000) -- 没连上, 或者断开了? 等2秒重试
        else
            log.info("wifi", "wifi NOT ready yet")
            sys.waitUntil("WLAN_READY", 30000)
        end
    end
end)
sys.run()

廉价的wifi模块,不到10块钱。

以上方式还是比较难的,更加简单的方式,使用emq提供的mqtt服务器,连接如下

免费的公共 MQTT 5 服务器 | EMQEMQ 提供了一个免费的公共 MQTT 服务器,它完全实现了 MQTT 5.0 标准,支持 TLS/SSL 安全连接及共享订阅,您可将它用于 MQTT 学习、测试或原型制作。https://www.emqx.com/zh/mqtt/public-mqtt5-broker

直接拿来调试还是可以的,搭建emq服务器也是挺简单的,这里就不说了。 

8266 mqtt 纯c开发_pxw1992的博客-CSDN博客官方的demo说明太少,mqtt服务器python搭建的,调试起来有点费劲。基于tcp的mqtt。编译代码以及smartconfig ota,参考之前的博客。https://blog.csdn.net/pxw1992/article/details/122278933?spm=1001.2014.3001.5501

 然后使用上面的方式开发mqtt,可以通过mqtt修改波特率,终端的数据就可以通过mqtt发布到服务器,然后开启一个客户端订阅此消息就可以了,远程串口非常方便,上文的自己写的mqtt服务器仅供学习使用,不具有项目意义。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值