2018-02-28 18:48:04 -05:00
# GWSockets
2019-08-23 20:24:02 -04:00
2018-02-28 18:48:04 -05:00
WebSockets for GLua
2019-08-23 20:24:02 -04:00
## Usage
2019-05-18 14:05:31 -04:00
Place either `gmsv_gwsockets_win32.dll` (Windows) or `gmsv_gwsockets_linux.dll` (Linux) into your `GarrysMod/lua/bin` folder. On windows you will require the Visual C++ Redistributable 2017, which you can find [here ](https://support.microsoft.com/help/2977003/the-latest-supported-visual-c-downloads ).
2018-03-02 19:42:50 -05:00
2020-04-10 15:07:22 -04:00
*NOTE:* CentOS is currently not supported and appears to be having multiple issues. If you need the library to work on CentOS, compile it on CentOS using the instructions all the way at the bottom, but also replace the included ssl libraries with the ones provided by CentOS.
2020-04-10 15:07:02 -04:00
2018-03-27 00:32:23 -04:00
*NOTE:* Even though this module is mainly aimed at servers, it can also be used on clients. Just rename the module to `gmcl_gwsockets_os` and it will work on clientside as well.
2018-03-07 02:51:42 -05:00
You will also need to require the module in lua before you will be able to use it. You can do this running
2018-03-02 19:42:50 -05:00
```LUA
require("gwsockets")
```
2019-08-23 20:24:02 -04:00
## Documentation
2018-03-02 19:42:50 -05:00
### Connecting to a socket server
2019-08-23 20:24:02 -04:00
2018-03-03 19:56:59 -05:00
* First initialize a websocket instance using
*NOTE:* URL's must include the scheme ( Either `ws://` or `wss://` )
2022-04-17 08:09:32 -04:00
`Example: "wss://echo.websocket.events/api/socketserver"`
2018-03-03 19:56:59 -05:00
2019-08-23 20:24:02 -04:00
```LUA
2018-03-27 00:32:23 -04:00
GWSockets.createWebSocket( url, verifyCertificate=true )
2018-03-02 19:42:50 -05:00
```
2019-08-23 20:24:02 -04:00
2018-03-27 00:32:23 -04:00
*NOTE:* If you want your websockets to use SSL but don't have a trusted certificate, you can set the second parameter to false.
2018-03-02 19:42:50 -05:00
2020-06-28 19:11:39 -04:00
* If you are running certain versions of Linux (e.g. CentOS) it might be necessary to specify a different path for the root certificates. This is only required if you want to use SSL and verify set verifyCertificates to true when creating a websocket.
```LUA
GWSockets.addVerifyPath( "/etc/ssl/certs" )
```
2018-03-02 19:42:50 -05:00
* Next add any cookies or headers you would like to send with the initial request (Optional)
```LUA
WEBSOCKET:setHeader( key, value )
WEBSOCKET:setCookie( key, value )
```
2020-06-28 19:11:39 -04:00
2018-03-02 19:42:50 -05:00
* Add some callbacks (Optional)
```LUA
2018-03-27 00:32:23 -04:00
-- called when a message from the peer has been received
function WEBSOCKET:onMessage( msg ) end
-- called whenever anything goes wrong, this is always followed by a call to onDisconnected
function WEBSOCKET:onError( errMessage ) end
-- called as soon as the socket is connected
-- This is a good place to start sending messages
function WEBSOCKET:onConnected() end
-- called whenever the socket has been disconnected
-- this can either be because the socket has been requested to closed (either through user or error)
-- or because the peer has closed the connection
-- Note: If the peer does not close the connection gracefully, this might not be called until a write is attempted.
function WEBSOCKET:onDisconnected() end
2018-03-02 19:42:50 -05:00
```
* Lastly open the connection
2019-08-23 20:24:02 -04:00
2018-03-02 19:42:50 -05:00
```LUA
WEBSOCKET:open()
```
2018-03-27 00:32:23 -04:00
* Once the socket has been opened you can send messages using the `write` function
2019-08-23 20:24:02 -04:00
2018-03-02 19:42:50 -05:00
```LUA
WEBSOCKET:write( message )
```
2019-08-23 20:24:02 -04:00
2018-03-27 00:32:23 -04:00
*NOTE:* You can write messages to the socket before the connection has been established and the socket
will wait before sending them until the connection has been established. However, it is best practice
to only start sending in the onConnected() callback.
2018-03-02 19:42:50 -05:00
* You can close the websocket connection at any time using `close` OR `closeNow`
```LUA
WEBSOCKET:close()
WEBSOCKET:closeNow()
```
* `close` will wait for all queued messages to be sent and then gracefully close the connection
* `closeNow` will immediately terminate the connection and discard all queued messages
2018-03-27 00:32:23 -04:00
* You can cancel any queued outbound messages by calling
2019-08-23 20:24:02 -04:00
2018-03-27 00:32:23 -04:00
```LUA
WEBSOCKET:clearQueue()
```
2019-08-23 20:24:02 -04:00
2018-03-27 00:32:23 -04:00
* You can check if the websocket is connected using
2019-08-23 20:24:02 -04:00
2018-03-27 00:39:40 -04:00
```LUA
WEBSOCKET:isConnected()
```
2019-08-23 20:24:02 -04:00
2018-03-27 00:39:40 -04:00
*NOTE:* You should avoid using this and instead rely on the callbacks.
2018-03-27 00:32:23 -04:00
2018-03-02 19:42:50 -05:00
## Example:
2019-08-23 20:24:02 -04:00
2018-03-02 19:42:50 -05:00
```LUA
require("gwsockets")
2022-04-17 08:09:32 -04:00
local socket = GWSockets.createWebSocket("wss://echo.websocket.events/")
2018-03-02 19:42:50 -05:00
2018-03-07 02:51:42 -05:00
function socket:onMessage(txt)
2019-08-23 20:24:02 -04:00
print("Received: ", txt)
2018-03-07 02:51:42 -05:00
end
2018-03-02 19:42:50 -05:00
2018-03-07 02:51:42 -05:00
function socket:onError(txt)
2019-08-23 20:24:02 -04:00
print("Error: ", txt)
2018-03-02 19:42:50 -05:00
end
2018-03-07 02:51:42 -05:00
-- We start writing only after being connected here. Technically this is not required as this library
-- just waits until the socket is connected before sending, but it's probably good practice
function socket:onConnected()
2019-08-23 20:24:02 -04:00
print("Connected to echo server")
-- Write Echo once every second, 10 times
timer.Create("SocketWriteTimer", 1, 0, function()
print("Writing: ", "Echo")
socket:write("Echo")
end)
timer.Simple(10, function()
timer.Remove("SocketWriteTimer")
-- Even if some of the messages have not reached the other side yet, this type of close makes sure
-- to only close the socket once all queued messages have been received by the peer.
socket:close()
end)
2018-03-02 19:42:50 -05:00
end
2018-03-07 02:51:42 -05:00
function socket:onDisconnected()
2019-08-23 20:24:02 -04:00
print("WebSocket disconnected")
2018-03-02 19:42:50 -05:00
end
socket:open()
```
2018-03-04 20:18:51 -05:00
2019-08-23 20:24:02 -04:00
## Build
2019-08-24 00:16:04 -04:00
Requires [premake5 ](https://premake.github.io/download.html#v5 ).
2019-08-24 00:11:16 -04:00
Depending on your platform run one of the following commands to create a build script:
```console
premake5 --os=windows --file=BuildProjects.lua vs2010 # Windows
premake5 --os=linux --file=BuildProjects.lua gmake # Linux
premake5 --os=macosx --file=BuildProjects.lua gmake # Mac
```
2018-03-27 00:32:23 -04:00
Then use the appropriate generated solution for your system in the solutions/ folder and build the project.
2018-03-04 20:18:51 -05:00
### Windows
2019-08-23 20:24:02 -04:00
2019-08-24 00:11:16 -04:00
On Windows all you need to do is open the generated visual studio project and build the dll. All libraries and headers are provided already. If you wish to build the 64 bit version you just have to switch the build configuration to x64.
2018-03-04 20:18:51 -05:00
### Linux
2019-08-23 20:24:02 -04:00
2018-03-27 00:32:23 -04:00
On linux only essential programs for building C++ programs are required. On Ubuntu 64-bit these are:
2019-08-23 20:24:02 -04:00
2018-03-04 20:18:51 -05:00
```console
sudo apt-get install build-essential gcc-multilib g++-multilib
```
2018-03-27 00:32:23 -04:00
2019-08-24 00:11:16 -04:00
The required static libraries for linux are included in this repository to avoid library/header version mismatching, but feel free to use your OS' libraries instead.
To build the project simply run
```console
make # x86
make config=release_x86_64 # x64
```
2020-01-04 22:49:55 -05:00
### Possible Issues
2019-08-24 00:11:16 -04:00
2020-01-04 22:49:55 -05:00
This library uses OpenSSL built for Ubuntu, which sets the default search path for
root certificates to the one Ubuntu uses. There is a possibility, that this path
is different on other systems. In that case you will need to swap out the libssl.a
and libcrypto.a provided in this repositor with the ones provided by your
operating system.