~aleteoryx/nex.nelua

nex.nelua/README.md -rw-r--r-- 2.6 KiB
d32095e0Aleteoryx cleanup a lot 15 days ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# nex.nelua

[nightfall express](https://nightfall.city/nex/info/specification.txt)
and [nightfall postal service](https://nightfall.city/nps/info/specification.txt)
servers written in the [nelua](https://nelua.io) programming language.

these aren't intended as full servers, they serve entirely from code.
you'll need to write up your backend yourself, but it's more fun that
way.

this implementation relies on the `epoll` family of syscalls, so YMMV
on non-linux or non-freebsd systems.

## building

install the nelua compiler, clone the repo. `nex.nelua` and `nps.nelua`
are the 2 base scripts to play with. their implementations are
barebones but should serve as a good starting point.

once you're happy with your setup, make them into binaries with

    nelua -r -o nex nex.nelua
    nelua -r -o nps nps.nelua

and throw them up somewhere

## socket.nelua

a pretty minimal asynchronous socket library. it should have a
familiar-if-limited interface to anyone who has used a higher-level
asynchronous API. it is sufficient to implement most text-mode network
protocols, so long as they are not reliant on multiple sockets.

it exposes the following methods from its return value:

### `socket.listen_tcp(addr: string, conn_cap: uinteger, handler: function(): void)`

listens on the host/port in `addr`. panics if it can't connect or if
`addr` is malformed. `addr` is either of the format `IPV4:PORT` or
`{IPV6}:PORT`. passes the connection to `socket.listen_sock`.

### `socket.listen_sock(fd: cint, conn_cap: uinteger, handler: function(): void)`

`fd` must be a valid socket, bound to some address and ready to
`accept` incoming connections. as connections are made, `handler` will
be executed in the context of a coroutine. it is expected to call one
of the provided [yielding functions](#yielding-functions) eventually.

will begin refusing incoming requests at `conn_cap` open connections

if there is any error reading from or writing to the socket, the
handler coroutine is deleted and the connection is dropped.

it is unwise to `coroutine.yield` manually from the context of a
handler function.

### yielding functions

functions provided for handlers to interact with their associated
socket

#### `socket.send(data: string)`

writes `data` over the network

#### `socket.send_line(data: string)`

writes `data` over the network with newline appended

#### `socket.recv_line(): string`

waits for an incoming line of text. returns it with newline stripped

this function is not CRLF-aware, and you make need to strip those
manually.

#### `socket.end_conn()`

closes the connection and deletes this coroutine