<commit_before># yunity-sockets

Handles socket.io connections from clients (web, mobile, app, etc...).

It works like this:

- socket.io client connects and makes `authenticate` call with a `sessionId`
- server looks up to see if this session is mapped to a user in redis
  - if so, joins the connection to a `room` for that user id
  - if not, leaves connection open, but will not publish anything to it
- server listens for keyspace events on redis and when a session is added or removed, the room membership is updated accordingly
- server listens for messages sent to redis pubsub channel which contain user ids and message, and pushes messages to appropriate connections

It's intended to be used for one way communications only:

django app --> redis --> yunity-sockets --> client

## sessions vs users vs connections

The three concepts are all independent but related.

When a client connects, this is a connection (or client). There are many of these.

A connection may be associated with a session, multiple connections may share a session (e.g. multiple tabs in a browser). A connection may have no session.

A user may be a associated with a session, one user may have multiple sessions (e.g. on their phone, and on their laptop). A session might not have a user id.

## how to run it

```
git clone <EMAIL>@github.com:yunity/yunity-sockets.git
cd yunity-sockets
npm install
node index.js -w 5000 -p 5001
```

This starts socket.io server on port 5000 and admin server on port 5001.


Alternatively if you install it globally with npm install -g, you get an executable on the npm path:

```
yunity-sockets -w 5000 -p 5001
```

## redis sessions

To associate a session with a user id, write to redis with key `session-store-` and the user id as value, e.g.:

```
redis-cli set session-store-mysessionid myuserid
```

### list session/users

You can list session/user pairs with:

```
$ redis-cli --raw keys 'session-store-*' | xargs -n1 -I{} sh -c 'echo -n {}:; redis-cli --raw get {}'
session-store-eerwauvu9314k0swy11wm7pnrgoy442y:79
```

### clear all sessions (... and anything else stored in redis)

```
redis-cli flushall
```

## redis notifications

To send messages to users `PUBLISH` serialized json to key `notifications` with a message like this:

```json
{
  "users": [23, 5, 12],
  "data": {
    "any": "valid",
    "json": "in here"
  }
}
```

E.g.:

```
redis-cli publish notifications '{"users":["user5"],"data":{"a":"b"}}'
```

### Chat messages

Chat messages look like this:

```
{
  "users": [23, 5, 12],
  "type": "chat_message"
  "payload": {
    "chat_id": 3434,
    "message": {
      "sender": 82,
      "created_at": "2007-12-24T18:21:00.003",
      "type": "TEXT",
      "id": 124624,
      "content": "Hi John, how are you?"
    }
  }
}
```

This will be sent to any connections associated with these users.

## socket.io clients

To connect to server and begin receiving messages, connect as a socket.io client:

```js

var socket = require('socket.io-client')('http://localhost:5000');
var sessionId = 'foo';<commit_msg>Remove type field from example<commit_after># yunity-sockets

Handles socket.io connections from clients (web, mobile, app, etc...).

It works like this:

- socket.io client connects and makes `authenticate` call with a `sessionId`
- server looks up to see if this session is mapped to a user in redis
  - if so, joins the connection to a `room` for that user id
  - if not, leaves connection open, but will not publish anything to it
- server listens for keyspace events on redis and when a session is added or removed, the room membership is updated accordingly
- server listens for messages sent to redis pubsub channel which contain user ids and message, and pushes messages to appropriate connections

It's intended to be used for one way communications only:

django app --> redis --> yunity-sockets --> client

## sessions vs users vs connections

The three concepts are all independent but related.

When a client connects, this is a connection (or client). There are many of these.

A connection may be associated with a session, multiple connections may share a session (e.g. multiple tabs in a browser). A connection may have no session.

A user may be a associated with a session, one user may have multiple sessions (e.g. on their phone, and on their laptop). A session might not have a user id.

## how to run it

```
git clone <EMAIL>:yunity/yunity-sockets.git
cd yunity-sockets
npm install
node index.js -w 5000 -p 5001
```

This starts socket.io server on port 5000 and admin server on port 5001.


Alternatively if you install it globally with npm install -g, you get an executable on the npm path:

```
yunity-sockets -w 5000 -p 5001
```

## redis sessions

To associate a session with a user id, write to redis with key `session-store-` and the user id as value, e.g.:

```
redis-cli set session-store-mysessionid myuserid
```

### list session/users

You can list session/user pairs with:

```
$ redis-cli --raw keys 'session-store-*' | xargs -n1 -I{} sh -c 'echo -n {}:; redis-cli --raw get {}'
session-store-eerwauvu9314k0swy11wm7pnrgoy442y:79
```

### clear all sessions (... and anything else stored in redis)

```
redis-cli flushall
```

## redis notifications

To send messages to users `PUBLISH` serialized json to key `notifications` with a message like this:

```json
{
  "users": [23, 5, 12],
  "data": {
    "any": "valid",
    "json": "in here"
  }
}
```

E.g.:

```
redis-cli publish notifications '{"users":["user5"],"data":{"a":"b"}}'
```

### Chat messages

Chat messages look like this:

```
{
  "users": [23, 5, 12],
  "type": "chat_message"
  "payload": {
    "chat_id": 3434,
    "message": {
      "sender": 82,
      "created_at": "2007-12-24T18:21:00.003",
      "id": 124624,
      "content": "Hi John, how are you?"
    }
  }
}
```

This will be sent to any connections associated with these users.

## socket.io clients

To connect to server and begin receiving messages, connect as a socket.io client:

```js

var socket = require('socket.io-client')('http://localhost:5000');
var sessionId = 'foo';
{'fraction_non_alphanumeric': 0.11391162029459902, 'fraction_numerical': 0.02684124386252046, 'mean_word_length': 3.6720183486238533, 'pattern_counts': {'":': 33, '<': 5, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3966304', 'n_tokens_mistral': 2039, 'n_tokens_neox': 1841, 'n_words': 837}