Skip to content
Joshua Haas edited this page Sep 8, 2017 · 8 revisions

This is a very simple socket interface for sibyl. Unlike the CLI, you can use this if sibyl is running as a daemon.

Requirements

You just need an open port for the protocol to bind.

Config

Required

  • protocols - include socket

Optional

  • socket.port - port to listen on (default: 8767)
  • socket.internet - if True, listen for external connections (default: False)
  • socket.password - if set, require a password from clients
  • socket.privkey - path to private key to enable SSL
  • socket.pubkey - path to public key to enable SSL
  • socket.key_password - password to unlock the private key
  • socket.debug - log raw messages (WARNING: passwords sent over socket will be logged)

Notes

This starts a basic, threaded socket server inside sibyl. You can then use client.py to connect to the server and issue commands. If you want to use the GUI, you need PyQt4 installed (e.g. pip install PyQt4).

If you want to use SSL (recommended) you'll need to generate a public and private key yourself (for example). Both socket.pubkey and socket.privkey must be set in order for encryption to function. If your private key is protected by a password, enter it in socket.key_password.

Dev

If you want to interface with sibyl_socket it has a pretty simple message protocol. The general form of a message is:

<LENGTH> <TYPE> <TEXT>

Where LENGTH is the length of the entire message excluding the LENGTH field itself and the separating space. For exmple:

7 1 hello

And type is any of those defined in sibyl_socket.ClientThread. Their names and values are given below.

MSG_AUTH = 0
MSG_TEXT = 1

If sibyl_socket is configured to require a password, then the very first thing a client sends must be:

<LENGTH> 0 <PASSWORD>

Which will then yield any of the following response messages also defined in sibyl_socket.ClientThread:

6 0 OKAY
8 0 FAILED
6 0 NONE

The first two should be obvious, noting that sibyl_socket will close the connection immediately after a failed authentication. The third indicates that sibyl_socket does not need a password.

You can then send and receive messages in the format:

<LENGTH> 1 <TEXT>

As an example, here's a complete transaction from sibyl.log using the client.py script included in this repository (with log_level = debug and socket.debug = True in config). Currently it uses a slight hack to confirm when sibyl is finished, namely asking for an echo of a randomly generated string. If we execute:

$ python client.py -p password -e "hello"
Hello world!

We'll see something like this in the logs:

2017-09-01 17:18:35 | socket   | INF | Got new connection from 127.0.0.1:58750
2017-09-01 17:18:35 | socket   | DEB | recv "10 0 password3 1  7 1 hello36 1 echo DONE_1504300715.86_3354162347"
2017-09-01 17:18:35 | socket   | DEB | act typ=0 "password"
2017-09-01 17:18:35 | socket   | DEB | send "6 0 OKAY"
2017-09-01 17:18:35 | socket   | DEB | Successful auth from 127.0.0.1:58750
2017-09-01 17:18:35 | socket   | DEB | act typ=1 " "
2017-09-01 17:18:35 | socket   | DEB | act typ=1 "hello"
2017-09-01 17:18:35 | socket   | DEB | act typ=1 "echo DONE_1504300715.86_3354162347"
2017-09-01 17:18:35 | sibylbot | INF | CMD: sibylbot.hello from socket:127.0.0.1:58750@socket with ('w', 'proto:socket', '*')
2017-09-01 17:18:35 | sibylbot | DEB | Running send hook: room.bridge_tx
2017-09-01 17:18:36 | socket   | DEB | send "14 1 Hello world!"
2017-09-01 17:18:36 | sibylbot | INF | CMD: general.echo from socket:127.0.0.1:58750@socket with ('w', 'proto:socket', '*')
2017-09-01 17:18:36 | sibylbot | DEB | Running send hook: room.bridge_tx
2017-09-01 17:18:36 | socket   | DEB | send "31 1 DONE_1504300715.86_3354162347"
2017-09-01 17:18:36 | socket   | DEB | recv ""
2017-09-01 17:18:36 | socket   | DEB | Received EOS from 127.0.0.1:58750
2017-09-01 17:18:36 | socket   | INF | Connection closed 127.0.0.1:58750@socket

Credits

Clone this wiki locally