Created
June 10, 2020 08:34
-
-
Save cloudfreexiao/851af8acff4ae5cf225d2ff19a94d327 to your computer and use it in GitHub Desktop.
skynet websocket gate lib
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local skynet = require "skynet" | |
local socket = require "skynet.socket" | |
local socketdriver = require "skynet.socketdriver" | |
local websocket = require "http.websocket" | |
local wsserver = {} | |
local lfd -- listen socket fd | |
local maxclient | |
local client_number = 0 | |
local nodelay = false | |
local CMD = {} | |
local connection = {} | |
function wsserver.openclient(fd) | |
end | |
function wsserver.closeclient(fd) | |
local c = connection[fd] | |
if c then | |
connection[fd] = nil | |
websocket.close(fd) | |
end | |
end | |
function wsserver.start(handler) | |
assert(handler.message) | |
assert(handler.connect) | |
local MSG = {} | |
local function close_fd(fd) | |
local c = connection[fd] | |
if c ~= nil then | |
connection[fd] = nil | |
client_number = client_number - 1 | |
end | |
end | |
function MSG.connect(fd) | |
if client_number >= maxclient then | |
socketdriver.close(fd) | |
return | |
end | |
if nodelay then | |
socketdriver.nodelay(fd) | |
end | |
connection[fd] = true | |
client_number = client_number + 1 | |
local addr = websocket.addrinfo(fd) | |
handler.connect(fd, addr) | |
end | |
function MSG.handshake(fd, header, url) | |
end | |
function MSG.message(fd, msg, msg_type) | |
assert(msg_type == "binary" or msg_type == "text") | |
if connection[fd] then | |
handler.message(fd, msg) | |
else | |
skynet.error(string.format("Drop message from fd (%d) : %s", fd, msg)) | |
end | |
end | |
function MSG.ping(fd) | |
end | |
function MSG.pong(fd) | |
end | |
function MSG.close(fd, code, reason) | |
if fd ~= lfd then | |
if handler.disconnect then | |
handler.disconnect(fd) | |
end | |
close_fd(fd) | |
else | |
lfd = nil | |
end | |
end | |
function MSG.error(fd) | |
if fd == lfd then | |
socketdriver.close(fd) | |
skynet.error("gateserver close listen socket, accpet error:[Socket Error]") | |
else | |
if handler.error then | |
handler.error(fd, "[Socket Error]") | |
end | |
close_fd(fd) | |
end | |
end | |
----------------------------------------------- | |
----------------------------------------------- | |
function CMD.open(source, conf) | |
assert(not lfd) | |
local address = conf.address or "0.0.0.0" | |
local port = assert(conf.port) | |
local protocol = conf.protocol or "ws" | |
maxclient = conf.maxclient or 1024 | |
nodelay = conf.nodelay | |
lfd = socketdriver.listen(address, port) | |
socket.start( | |
lfd, | |
function(fd, addr) | |
skynet.error(string.format("accept client socket_fd: %s addr:%s", fd, addr)) | |
local ok, err = websocket.accept(fd, MSG, protocol, addr) | |
if not ok then | |
skynet.error("websocket accept error:", err) | |
end | |
end | |
) | |
end | |
function CMD.close() | |
assert(lfd) | |
socketdriver.close(lfd) | |
end | |
skynet.register_protocol { | |
name = "socket", | |
id = skynet.PTYPE_SOCKET -- PTYPE_SOCKET = 6 | |
} | |
skynet.start( | |
function() | |
skynet.dispatch( | |
"lua", | |
function(_, address, cmd, ...) | |
local f = CMD[cmd] | |
if f then | |
skynet.ret(skynet.pack(f(address, ...))) | |
else | |
skynet.ret(skynet.pack(handler.command(cmd, address, ...))) | |
end | |
end | |
) | |
end | |
) | |
end | |
return wsserver |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment