You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
110 lines
1.9 KiB
Lua
110 lines
1.9 KiB
Lua
local socket = require "skynet.socket"
|
|
local skynet = require "skynet"
|
|
|
|
local readbytes = socket.read
|
|
local writebytes = socket.write
|
|
|
|
local sockethelper = {}
|
|
local socket_error = setmetatable({} , { __tostring = function() return "[Socket Error]" end })
|
|
|
|
sockethelper.socket_error = socket_error
|
|
|
|
local function preread(fd, str)
|
|
return function (sz)
|
|
if str then
|
|
if sz == #str or sz == nil then
|
|
local ret = str
|
|
str = nil
|
|
return ret
|
|
else
|
|
if sz < #str then
|
|
local ret = str:sub(1,sz)
|
|
str = str:sub(sz + 1)
|
|
return ret
|
|
else
|
|
sz = sz - #str
|
|
local ret = readbytes(fd, sz)
|
|
if ret then
|
|
return str .. ret
|
|
else
|
|
error(socket_error)
|
|
end
|
|
end
|
|
end
|
|
else
|
|
local ret = readbytes(fd, sz)
|
|
if ret then
|
|
return ret
|
|
else
|
|
error(socket_error)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function sockethelper.readfunc(fd, pre)
|
|
if pre then
|
|
return preread(fd, pre)
|
|
end
|
|
return function (sz)
|
|
local ret = readbytes(fd, sz)
|
|
if ret then
|
|
return ret
|
|
else
|
|
error(socket_error)
|
|
end
|
|
end
|
|
end
|
|
|
|
sockethelper.readall = socket.readall
|
|
|
|
function sockethelper.writefunc(fd)
|
|
return function(content)
|
|
local ok = writebytes(fd, content)
|
|
if not ok then
|
|
error(socket_error)
|
|
end
|
|
end
|
|
end
|
|
|
|
function sockethelper.connect(host, port, timeout)
|
|
local fd
|
|
if timeout then
|
|
local drop_fd
|
|
local co = coroutine.running()
|
|
-- asynchronous connect
|
|
skynet.fork(function()
|
|
fd = socket.open(host, port)
|
|
if drop_fd then
|
|
-- sockethelper.connect already return, and raise socket_error
|
|
socket.close(fd)
|
|
else
|
|
-- socket.open before sleep, wakeup.
|
|
skynet.wakeup(co)
|
|
end
|
|
end)
|
|
skynet.sleep(timeout)
|
|
if not fd then
|
|
-- not connect yet
|
|
drop_fd = true
|
|
end
|
|
else
|
|
-- block connect
|
|
fd = socket.open(host, port)
|
|
end
|
|
if fd then
|
|
return fd
|
|
end
|
|
error(socket_error)
|
|
end
|
|
|
|
function sockethelper.close(fd)
|
|
socket.close(fd)
|
|
end
|
|
|
|
function sockethelper.shutdown(fd)
|
|
socket.shutdown(fd)
|
|
end
|
|
|
|
return sockethelper
|