mirror of
https://github.com/Ale32bit/Capy64.git
synced 2025-01-18 18:46:43 +00:00
Improved WS client object
This commit is contained in:
parent
bc87363f7c
commit
c2aca7a7af
3 changed files with 67 additions and 66 deletions
|
@ -2,23 +2,6 @@ local http = require("http")
|
||||||
local event = require("event")
|
local event = require("event")
|
||||||
local expect = require("expect").expect
|
local expect = require("expect").expect
|
||||||
|
|
||||||
local WebSocketHandle = {}
|
|
||||||
function WebSocketHandle:close()
|
|
||||||
self:closeAsync()
|
|
||||||
local _, id
|
|
||||||
repeat
|
|
||||||
_, id = event.pull("websocket_close")
|
|
||||||
until id == self.requestId
|
|
||||||
end
|
|
||||||
|
|
||||||
function WebSocketHandle:receive()
|
|
||||||
local _, id, par
|
|
||||||
repeat
|
|
||||||
_, id, par = event.pull("websocket_message")
|
|
||||||
until id == self.requestId
|
|
||||||
|
|
||||||
return par
|
|
||||||
end
|
|
||||||
|
|
||||||
function http.request(url, body, headers, options)
|
function http.request(url, body, headers, options)
|
||||||
expect(1, url, "string")
|
expect(1, url, "string")
|
||||||
|
@ -60,12 +43,27 @@ function http.post(url, body, headers, options)
|
||||||
return http.request(url, body, headers, options)
|
return http.request(url, body, headers, options)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function buildWebsocketHandle(requestId, handle)
|
local WebSocketHandle
|
||||||
handle.requestId = requestId
|
local function buildWebsocketHandle(handle)
|
||||||
local metatable = getmetatable(handle) or {}
|
if not WebSocketHandle then
|
||||||
metatable.__index = WebSocketHandle
|
WebSocketHandle = getmetatable(handle) or { __index = {} }
|
||||||
|
function WebSocketHandle.__index:close()
|
||||||
|
self:closeAsync()
|
||||||
|
local _, id
|
||||||
|
repeat
|
||||||
|
_, id = event.pull("websocket_close")
|
||||||
|
until id == self:getRequestID()
|
||||||
|
end
|
||||||
|
|
||||||
setmetatable(handle, metatable)
|
function WebSocketHandle.__index:receive()
|
||||||
|
local _, id, par
|
||||||
|
repeat
|
||||||
|
_, id, par = event.pull("websocket_message")
|
||||||
|
until id == self:getRequestID()
|
||||||
|
|
||||||
|
return par
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return handle
|
return handle
|
||||||
end
|
end
|
||||||
|
@ -88,5 +86,5 @@ function http.websocket(url, headers)
|
||||||
return nil, par
|
return nil, par
|
||||||
end
|
end
|
||||||
|
|
||||||
return buildWebsocketHandle(requestId, par)
|
return buildWebsocketHandle(par)
|
||||||
end
|
end
|
||||||
|
|
|
@ -332,7 +332,7 @@ public class HTTP : IPlugin
|
||||||
|
|
||||||
await task;
|
await task;
|
||||||
|
|
||||||
var handle = new WebSocketHandle(wsClient, requestId, _game);
|
var handle = new WebSocketHandle(wsClient, requestId);
|
||||||
WebSocketConnections.Add(handle);
|
WebSocketConnections.Add(handle);
|
||||||
|
|
||||||
_game.LuaRuntime.QueueEvent("websocket_connect", LK =>
|
_game.LuaRuntime.QueueEvent("websocket_connect", LK =>
|
||||||
|
@ -368,10 +368,11 @@ public class HTTP : IPlugin
|
||||||
|
|
||||||
if (result.EndOfMessage)
|
if (result.EndOfMessage)
|
||||||
{
|
{
|
||||||
|
var payload = builder.ToString();
|
||||||
_game.LuaRuntime.QueueEvent("websocket_message", LK =>
|
_game.LuaRuntime.QueueEvent("websocket_message", LK =>
|
||||||
{
|
{
|
||||||
LK.PushInteger(requestId);
|
LK.PushInteger(requestId);
|
||||||
LK.PushString(builder.ToString());
|
LK.PushString(payload);
|
||||||
|
|
||||||
return 2;
|
return 2;
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,78 +2,80 @@
|
||||||
using KeraLua;
|
using KeraLua;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Net.WebSockets;
|
using System.Net.WebSockets;
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Capy64.Runtime.Objects.Handlers;
|
namespace Capy64.Runtime.Objects.Handlers;
|
||||||
|
|
||||||
public class WebSocketHandle
|
public class WebSocketHandle
|
||||||
{
|
{
|
||||||
private ClientWebSocket _client;
|
public const string ObjectType = "WebSocketClient";
|
||||||
private long _requestId;
|
private readonly ClientWebSocket _socket;
|
||||||
private static IGame _game;
|
private readonly long _requestId;
|
||||||
public WebSocketHandle(ClientWebSocket client, long requestId, IGame game)
|
public WebSocketHandle(ClientWebSocket socket, long requestId)
|
||||||
{
|
{
|
||||||
_client = client;
|
_socket = socket;
|
||||||
_requestId = requestId;
|
_requestId = requestId;
|
||||||
_game = game;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly Dictionary<string, LuaFunction> functions = new()
|
private static readonly Dictionary<string, LuaFunction> functions = new()
|
||||||
{
|
{
|
||||||
|
["getRequestID"] = L_GetRequestId,
|
||||||
["send"] = L_Send,
|
["send"] = L_Send,
|
||||||
["closeAsync"] = L_CloseAsync,
|
["closeAsync"] = L_CloseAsync,
|
||||||
};
|
};
|
||||||
|
|
||||||
public void Push(Lua L)
|
public void Push(Lua L)
|
||||||
{
|
{
|
||||||
L.NewTable();
|
L.PushObject(this);
|
||||||
|
|
||||||
// metatable
|
if (L.NewMetaTable(ObjectType))
|
||||||
L.NewTable();
|
|
||||||
L.PushString("__close");
|
|
||||||
L.PushCFunction(L_CloseAsync);
|
|
||||||
L.SetTable(-3);
|
|
||||||
L.PushString("__gc");
|
|
||||||
L.PushCFunction(L_CloseAsync);
|
|
||||||
L.SetTable(-3);
|
|
||||||
L.SetMetaTable(-2);
|
|
||||||
|
|
||||||
foreach (var pair in functions)
|
|
||||||
{
|
{
|
||||||
L.PushString(pair.Key);
|
L.PushString("__index");
|
||||||
L.PushCFunction(pair.Value);
|
L.NewTable();
|
||||||
|
foreach (var pair in functions)
|
||||||
|
{
|
||||||
|
L.PushString(pair.Key);
|
||||||
|
L.PushCFunction(pair.Value);
|
||||||
|
L.SetTable(-3);
|
||||||
|
}
|
||||||
|
L.SetTable(-3);
|
||||||
|
|
||||||
|
L.PushString("__close");
|
||||||
|
L.PushCFunction(L_CloseAsync);
|
||||||
|
L.SetTable(-3);
|
||||||
|
|
||||||
|
L.PushString("__gc");
|
||||||
|
L.PushCFunction(L_CloseAsync);
|
||||||
L.SetTable(-3);
|
L.SetTable(-3);
|
||||||
}
|
}
|
||||||
|
|
||||||
L.PushString("_handle");
|
L.SetMetaTable(-2);
|
||||||
L.PushObject(this);
|
|
||||||
L.SetTable(-3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static WebSocketHandle GetHandle(Lua L, bool gc = true)
|
private static int L_GetRequestId(IntPtr state)
|
||||||
{
|
{
|
||||||
L.CheckType(1, LuaType.Table);
|
var L = Lua.FromIntPtr(state);
|
||||||
L.PushString("_handle");
|
|
||||||
L.GetTable(1);
|
var client = L.CheckObject<WebSocketHandle>(1, ObjectType, false);
|
||||||
return L.ToObject<WebSocketHandle>(-1, gc);
|
|
||||||
|
L.PushInteger(client._requestId);
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int L_Send(IntPtr state)
|
private static int L_Send(IntPtr state)
|
||||||
{
|
{
|
||||||
var L = Lua.FromIntPtr(state);
|
var L = Lua.FromIntPtr(state);
|
||||||
|
|
||||||
|
var client = L.CheckObject<WebSocketHandle>(1, ObjectType, false);
|
||||||
|
|
||||||
var data = L.CheckBuffer(2);
|
var data = L.CheckBuffer(2);
|
||||||
|
|
||||||
var h = GetHandle(L, false);
|
if (client is null || client._socket.State == WebSocketState.Closed)
|
||||||
|
|
||||||
if (h is null || h._client.State == WebSocketState.Closed)
|
|
||||||
L.Error("connection is closed");
|
L.Error("connection is closed");
|
||||||
|
|
||||||
h._client.SendAsync(data, WebSocketMessageType.Text, true, CancellationToken.None);
|
client._socket.SendAsync(data, WebSocketMessageType.Text, true, CancellationToken.None);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -82,24 +84,24 @@ public class WebSocketHandle
|
||||||
{
|
{
|
||||||
var L = Lua.FromIntPtr(state);
|
var L = Lua.FromIntPtr(state);
|
||||||
|
|
||||||
var h = GetHandle(L, true);
|
var client = L.CheckObject<WebSocketHandle>(1, ObjectType, true);
|
||||||
|
|
||||||
if (h is null || h._client.State == WebSocketState.Closed)
|
if (client is null || client._socket.State == WebSocketState.Closed)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
h._client.CloseAsync(WebSocketCloseStatus.NormalClosure, null, CancellationToken.None)
|
client._socket.CloseAsync(WebSocketCloseStatus.NormalClosure, null, CancellationToken.None)
|
||||||
.ContinueWith(async task =>
|
.ContinueWith(async task =>
|
||||||
{
|
{
|
||||||
await task;
|
await task;
|
||||||
_game.LuaRuntime.QueueEvent("websocket_close", LK =>
|
Capy64.Instance.LuaRuntime.QueueEvent("websocket_close", LK =>
|
||||||
{
|
{
|
||||||
LK.PushInteger(h._requestId);
|
LK.PushInteger(client._requestId);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
HTTP.WebSocketConnections.Remove(h);
|
HTTP.WebSocketConnections.Remove(client);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue