skynet使用json收发数据

本文档展示了如何在Skynet中使用JSON进行数据收发。通过启动配置文件`config.skynet_json`,Skynet API 启动了多个服务,包括一个监听8888端口的主服务。客户端`client.lua`发送登录消息`handshake`,接收到响应后,继续发送用户名`wangwu`和`lisi`,并成功接收对应的登录确认数据。
部署运行你感兴趣的模型镜像

skynet api

常用的api

skynet.newservice
skynet.fork
skynet.start
skynet.dispatch


socket.listen
socket.start
socket.read,write(require "socket") !!!
socket.recv,send(require "client.socket")

cjson.decode
cjson.encode

main.lua

--[[
常用的api

skynet.newservice
skynet.fork
skynet.start
skynet.dispatch


socket.listen
socket.start
socket.read,write(require "socket") !!!
socket.recv,send(require "client.socket")

cjson.decode
cjson.encode
]]

local skynet = require "skynet"
local socket = require "skynet.socket"

local function accept(clientfd, addr)
    skynet.newservice("agent", clientfd, addr)
end

skynet.start(function ()
    local listenfd = socket.listen("0.0.0.0", 8888)
    skynet.error("listen on 0.0.0.0, 8888")
    socket.start(listenfd, accept)
end)

agent.lua

local skynet = require "skynet"
local socket = require "skynet.socket"
local cjson = require "cjson"


local clientfd, addr=...
clientfd = tonumber(clientfd)

-- 打包发送一个数据包,加上大端2字节的头部
local function send_package(fd, pack)
	local package = string.pack(">s2", pack)
	socket.write(fd, package)
end

-- 解析数据包  返回值第一个为完整的包,第二个为剩余的
local function unpack_package(text)
    if text == nil then 
        return nil, text
    end
	local size = #text
	if size < 2 then 
		return nil, text
	end
	local s = text:byte(1) * 256 + text:byte(2) --数据包的长度
	if size < s+2 then
		return nil, text
	end
    -- 从第三个字节开始,到数据包结束, 
	return text:sub(3,2+s), text:sub(3+s)--前一个完整数据包的后续
end

-- 返回一个完整包,读取数据,拼接剩余的
local function recv_package(last)
	local result
	result, last = unpack_package(last)
	if result then
		return result, last --result是完整的数据包
	end
    local r = socket.read(clientfd)
    if not r then
		return nil, last
    end
	if r == "" then
		error "Server closed"
	end
	return unpack_package(last .. r)
end

local last = ""
local function process_socket_events()
    --[[
        while true do
        local r = socket.read(clientfd)
        if r then 
            print(r)
        else
            print("recv nil")
        end
    end
    ]]

    while true do
		local v
		v, last = recv_package(last)
        if not v then
            skynet.error("fd = ",clientfd," socket closed")
            skynet.exit()
			break
		end
        print(v)
        send_package(clientfd,v)
	end   
end

skynet.start(function ()
    print("recv a connection:", clientfd, addr)
    
    socket.start(clientfd) -- 绑定 fd actorid 与epoll事件
    skynet.fork(process_socket_events)

    skynet.dispatch("lua", function (_, _, cmd, ...)
        
    end)
end)

client.lua

package.cpath = "../../skynet/luaclib/?.so;../../lua-cjson/?.so;"
package.path = "../../skynet/lualib/?.lua;./skynet/examples/?.lua;;../../lua-cjson/?.lua"


local cjson = require "cjson"
local socket = require "client.socket"

local fd = assert(socket.connect("127.0.0.1", 8888))

local function send_package(fd, pack)
	local json = {}
	json["cmd"] = "login"
	json["data"] = pack
	local data = cjson.encode(json);
    local package = string.pack(">s2", data)
    socket.send(fd, package)
end

local function unpack_package(text)
    local size = #text
    if size < 2 then
        return nil, text
    end
    local s = text:byte(1) * 256 + text:byte(2)
    if size < s+2 then
        return nil, text
    end

    return text:sub(3,2+s), text:sub(3+s)
end

local function recv_package(last)
    local result
    result, last = unpack_package(last)
    if result then
        return result, last
    end
    local r = socket.recv(fd)
    if not r then
        return nil, last
    end
    if r == "" then
        error "Server closed"
    end
    return unpack_package(last .. r)
end

local session = 0

local function send_request(str)
    print("send msg:",str)
    send_package(fd, str)
end

local last = ""

local function dispatch_package()
    while true do
        local v
        v, last = recv_package(last)
        if not v then
            break
		end
		v = cjson.decode(v)
		print("recv msg;",v)
		print("cmd = ",v.cmd)
		print("data = ",v.data)
    end
end

send_request("handshake")
while true do
    dispatch_package()
    local cmd = socket.readstdin()
    if cmd then
        if cmd == "quit" then
            socket.close(fd)
            break
        else
            send_request(cmd)
        end
    else
        socket.usleep(100)
    end
end

config.skynet_json

thread=8--工作线程数目
logger=nil
harbor=0
start="main" -- 启动第一服务 
lua_path="./skynet/lualib/?.lua;".."./test/lualib/?.lua;".."./skynet/lualib/?/init.lua;".."./lua-cjson/?.lua"
luaservice = "./skynet/service/?.lua;".."./myexample/skynet_json/?.lua;".."./skynet/test/?.lua;".."./lua-cjson/?.lua;"
lualoader = "./skynet/lualib/loader.lua"
cpath = "./skynet/cservice/?.so;./lua-cjson/?.so" -- actor 内存块 + 消息队列
lua_cpath = "./skynet/luaclib/?.so;".."./lua-cjson/?.so" -- C语言写的lua库

gdut17@ubuntu:~/skynet_test$ ./skynet/skynet config.skynet_json
[:00000002] LAUNCH snlua bootstrap
[:00000003] LAUNCH snlua launcher
[:00000004] LAUNCH snlua cdummy
[:00000005] LAUNCH harbor 0 4
[:00000006] LAUNCH snlua datacenterd
[:00000007] LAUNCH snlua service_mgr
[:00000008] LAUNCH snlua main
[:00000008] listen on 0.0.0.0, 8888
[:00000002] KILL self
[:0000000a] LAUNCH snlua agent 2 127.0.0.1:48656
recv a connection: 2 127.0.0.1:48656
{“data”:“handshake”,“cmd”:“login”}
[:0000000a] 2 socket closed
[:0000000a] KILL self
[:00000012] LAUNCH snlua agent 3 127.0.0.1:48658
recv a connection: 3 127.0.0.1:48658
{“cmd”:“login”,“data”:“handshake”}
{“cmd”:“login”,“data”:“wangwu”}
{“cmd”:“login”,“data”:“lisi”}

gdut17@ubuntu:~/skynet_test/myexample/skynet_json$ lua client.lua
send msg: handshake
recv msg; table: 0x5624fcaf0a50
cmd = login
data = handshake
wangwu
send msg: wangwu
recv msg; table: 0x5624fcaf0cd0
cmd = login
data = wangwu
lisi
send msg: lisi
recv msg; table: 0x5624fcaf0f10
cmd = login
data = lisi

您可能感兴趣的与本文相关的镜像

Wan2.2-T2V-A5B

Wan2.2-T2V-A5B

文生视频
Wan2.2

Wan2.2是由通义万相开源高效文本到视频生成模型,是有​50亿参数的轻量级视频生成模型,专为快速内容创作优化。支持480P视频生成,具备优秀的时序连贯性和运动推理能力

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值