ZMQ在线docs:http://api.zeromq.org/2-1-3:_start
1,序言,zmq 作为一种通信比较好,快捷的方式,越来越多的开发者使用。
这里提供一个简单的例子来叙述lua_zmq的通信方式:案例是在Mac电脑编写
1,先说zmq中req和rep方式,rep 作为服务端,req作为请求端,req只有先收到req的请求后,才会发消息回复,同理,req只有发送请求后,才会得到rep的消息相应。流程不可变,
上代码:
服务端rep:
require "zhelpers"
local zmq = require "lzmq" -- 获取zmq的安装包
local context = zmq.context() -- 创建一个ZMQ 上下文 ,
local publisher, err = context:socket{zmq.REP, bind = "tcp://*:5025"} -- 调用套接字 服务端将套接字绑定在端口5025
zassert(publisher, err) -- 开始等待响应 发出应答 如此循环
-- 客户端是发送请求 并等待服务端的应答
local y = 0
while y>=0 do
local x = "This is a zmq test!"
y = y + 1
local ret = zassert(publisher:recv())
print(y.."rep recv"..ret)
sleep(1)
zassert(publisher:send(x))
-- print(y..":"..x)
end
客户端 req:
---------------------------------------req------------------------------------
require "zhelpers"
local zmq = require "lzmq"
local context = zmq.context();
local requester,err = context:socket{zmq.REQ,connect = "tcp://localhost:5025"}
zassert(requester,err)
for i = 1,10 do
-- print("hello world")
zassert(requester:send("hello"));
local ret = requester:recv()
print("req recv==="..ret)
end
2,方式2 zmq中的Sub和Pub,发布和订阅式,Pub可以发布许多消息给不同的用户,Sub通过filter 筛选自 己所需要的内容:
pub端:
require "zhelpers"
local zmq = require "lzmq" -- 获取zmq的安装包
local context = zmq.context() -- 创建一个ZMQ 上下文 ,
local publisher, err = context:socket{zmq.PUB, bind = "tcp://*:7002"} -- 调用套接字 服务端将套接字绑定在端口6801
zassert(publisher, err) -- 开始等待响应 发出应答 如此循环
-- 客户端是发送请求 并等待服务端的应答
local y = 0
while y>=0 do
local x = "This is a zmq test"
local xx = "This is a zmq test too"
local xxx = "This is a zmq test too too"
y = y + 1
-- local ret = zassert(publisher:recv())
-- print(y.."rep recv"..ret)
sleep(1)
zassert(publisher:send(x))
zassert(publisher:send(xx))
zassert(publisher:send(xxx))
sleep(1)
print(y..":"..x..xx..xx)
end
sub端
--------------------------SUB-------------------
SUB会过滤PUB来得消息,由filter来定义数据格式
local filter =""
printf("Collecting updates from weather server ...\n")
local context = zmq.context()
local subscriber, err = context:socket{zmq.SUB,
-- subscribe = filter;
-- connect = "tcp://172.15.2.4:6000";
connect = "tcp://*:7002";
}
zassert(subscriber,err)
print(subscriber)
local update_nbr, total_temp = 100, 0
-- for i = 1, update_nbr do
while(1) do
print("~~~~~~~~~~~")
local message = subscriber:recv()
-- local y = {}
-- y = string.split(message,%s)
-- print(y..":"..#y)
local x = ""
local table1 = {}
for name1 in string.gmatch(message,"([%d]*)%s+([-]?[%d-]*)%s+([-]?[%d-]*)") do
table.insert(table1.name1)
print(name1)
end
for i=1,7 do
-- x = x..table1[i]..","
print(i)
print(table1[i])
end
-- for name2 in string.gmatch(message,"title_name %w+") do
-- print(name2)
-- x = x..","..name2
-- end
print(x)
print(total_temp.."-> "..message)
total_temp = total_temp + 1
end
3,lua 中的socket通信,案例中只有发送以及接受消息,并没有回复的设置,代码后续完善:
socket 通过绑定一个IP地址,端口号,来实现两台机子之间的通信过程。
服务端Server:
-- server.lua
local socket = require("socket")
-- local host = "127.0.0.1"
local host = "192.168.0.100"
local port = "12346"
local server = assert(socket.bind(host, port, 1024))
server:settimeout(0)
local client_tab = {}
local conn_count = 0
print("Server Start " .. host .. ":" .. port)
while 1 do
local conn = server:accept()
if conn then
conn_count = conn_count + 1
client_tab[conn_count] = conn
print("A client successfully connect!")
end
for conn_count, client in pairs(client_tab) do
local recvt, sendt, status = socket.select({client}, nil, 1)
if #recvt > 0 then
local receive, receive_status = client:receive()
if receive_status ~= "closed" then
if receive then
assert(client:send("Client " .. conn_count .. " Send : "))
assert(client:send(receive .. "\n"))
print("Receive Client " .. conn_count .. " : ", receive)
end
else
table.remove(client_tab, conn_count)
client:close()
print("Client " .. conn_count .. " disconnect!")
end
end
end
end
客户端Client:
– client.lua
local socket = require("socket")
local host = "192.168.0.100"
local port = "12346"
local sock = assert(socket.connect(host, port))
sock:settimeout(0)
print("Press enter after input something:")
local input, recvt, sendt, status
while true do
input = io.read()
if #input > 0 then
assert(sock:send(input .. "\n"))
end
recvt, sendt, status = socket.select({sock}, nil, 1)
while #recvt > 0 do
local response, receive_status = sock:receive()
if receive_status ~= "closed" then
if response then
print(response)
recvt, sendt, status = socket.select({sock}, nil, 1)
end
else
break
end
end
end