hello-skynet之五:hello-socket
本节任务,在hello-console的基础上,
用snlua服务实现 socket echo服务器和客户端.
关于socket的使用请参考skynet的wiki, 这里只是用到了最简单的几个函数。
注意:从本节开始,我们将延续hello-console的思想,把skynet作为一个虚拟机,手动敲服务名(server/client)来分别加载对应的服务。
1、复制hello-console文件夹为hello-socket,删除除以下文件外的其它文件:
- config.lua –共用配置文件
- main.lua –共用启动入口服务
2、修改config.lua里的app_name为当前项目目录名(hello-socket),并添加服务端监听地址参数
app_name = "hello-socket"
app_root = _root..app_name.."/"
app_server = "0.0.0.0:7000"
3、服务端的服务,普通的snlua,每个客户端一个协程。协程会尽量读取客户端数据,然后打印出来。
local skynet = require "skynet"
local socket = require "socket"
--简单echo服务
function echo(id, addr)
socket.start(id)
while true do
local str = socket.read(id)
if str then
skynet.error("client"..id, " says: ", str)
socket.write(id, str)
else
socket.close(id)
skynet.error("client"..id, " ["..addr.."]", "disconnected")
return
end
end
end
--服务入口
skynet.start(function()
local id = assert(socket.listen(skynet.getenv "app_server"))
socket.start(id, function(id, addr)
skynet.error("client"..id, " ["..addr.."]", "connected")
skynet.fork(echo, id, addr)
end)
end)
4、客户端服务,连接服务端,发送字符串,并等待服务端反馈,退出
local skynet = require "skynet"
local socket = require "socket"
local name = ... or ""
function _read(id)
while true do
local str = socket.read(id)
if str then
skynet.error(id, "server says: ", str)
socket.close(id)
skynet.exit()
else
socket.close(id)
skynet.error("disconnected")
skynet.exit()
end
end
end
skynet.start(function()
--连接到服务器
local addr = skynet.getenv "app_server"
local id = socket.open(addr)
if not id then
skynet.error("can't connect to "..addr)
skynet.exit()
end
skynet.error("connected")
--启动读协程
skynet.fork(_read, id)
socket.write(id, "hello, "..name)
end)
5、测试
分别打开两个终端(使用同样的命令)
skynet/skynet hello-socket/config.lua
第一个终端,输入 server 启动服务端;
server
[:0000000b] LAUNCH snlua server
第二个终端,输入 client 启动客户段;
client
[:0000000b] LAUNCH snlua client
[:0000000b] connected
[:0000000b] 3 server says: hello,
[:0000000b] KILL self
此时服务端输出:
[:0000000b] client4 [127.0.0.1:58067] connected
[:0000000b] client4 says: hello,
[:0000000b] client4 [127.0.0.1:58067] disconnected
可以看到客户端连接上服务端,并收到了服务端的反馈信息,然后kill self.
上面的客户没有名字,你可以试着输入 client world 给客户段起个叫”world”的名字试试看结果。
6、未涉及内容:
<br />
socket.block 等待一个 socket 可读<br />
socket.lwrite(id, str) 低优先级队列<br />
udp udp<br />
dns 非阻塞名字查询<br />
Written on June 4, 2015