Skip to content

Scatter - Free and Open Source WebSocket standalone message server

License

Notifications You must be signed in to change notification settings

scatter-server/scatter

Repository files navigation

WsServer - WebSocket Open Message Server

Build Status

Codacy Badge

About

Simple, standalone, websocket high-performance message server.

Features

  • Native Multi-threading (boostthread pool)
  • Undelivered messages queue (with TTL in future)
  • Multiple recipients in one message
  • Transparent admin user (use sender=0)
  • ws/wss protocols (text, binary (but useless now))
  • Support fragmented frame buffer
  • JSON payload
  • User-independent (negative side - user id can be only unsigned long number, strings not supported now)
  • Payload size limit
  • Multiple connections per user (hello Whatsapp 👽)
  • Watchdog. Check for alive connections, using PING-PONG.
  • REST Api server
    • list active users with simple statistics
    • sending message
    • simple statistics for all or each user
    • checking user is online
  • Event notifier. Server send message copy to your server. Supports couple auth methods: basic, header-based, bearer, cookie, et cetera (see Configuring section)
    • url-based postbacks (or webhook as you like)
    • redis (queue (rpush) and pubsub channel publishing)

Todo features

  • Lock-free queues (now implemented only for events thx to cameron314)
  • Horizontal scaling (custom cluster or using another solution)
  • Persistence for queued messages
  • Runtime switch using ws/wss protocol (now only at compile time: -DUSE_SSL=ON)
  • Event notifier targets:
    • SQL (PostgreSQL, MySQL)
    • MongoDB
    • Maybe: Cloud DBs (like Firebase RTD)
    • Maybe: some message queue like RabbitMQ
    • Maybe: unix socket, tcp or udp, or all of this

Downloads

Prebuilt binaries available for download here

Install

  • Debian**
sudo dpkg -i wsserver.deb
sudo apt-get -f install
  • Centos
yum install wsserver.rpm
# or
rpm -i wsserver.rpm

Requirements

  • GCC/CLang: -stdlib=c++14
  • CMake
  • Boost 1.54.0+ (recommended 1.60+)
    • Boost (system thread coroutine context random, GCC < 4.9 - regex)
    • Boost 1.63 requires CMake 3.7 or newer
    • Boost 1.64 requires CMake 3.8 or newer
    • Boost 1.65 and 1.65.1 require CMake 3.9.3 or newer
    • Boost.Asio
  • libcrypto/libssl (OpenSSL) 1.1.1+ (bundled for x86-64 linux and macOS)
  • libcurl-ssl-dev
  • ToolBox++ (https://github.com/edwardstock/toolboxpp)

Clone (with submodules)

git clone --recursive https://github.com/edwardstock/wsserver.git

Prepare to build

CMake options

  • -DBOOST_ROOT=/path/to/boost
  • -DENABLE_SSL=On|Off - use secure server certificates required
  • -DENABLE_REDIS_TARGET=On|Off - enable event notifier redis target

Prepare Centos7

  • GCC-7 (if not installed (required 4.9+, recommended 6+))
yum install centos-release-scl
yum install devtoolset-7-gcc*
scl enable devtoolset-7 bash
  • Dependencies
yum install openssl openssl-devel curl libcurl-devel
  • Boost
# icu required for unicode regexes
yum install libicu-devel

wget https://dl.bintray.com/boostorg/release/1.66.0/source/boost_1_66_0.tar.gz
tar -xzf boost_1_66_0.tar.gz && cd boost_1_66_0
./bootstrap.sh --prefix=/opt/boost1660
./b2 install --prefix=/opt/boost1660 --with=all

Prepare Debian 9/10 (stretch or buster)

apt-get install libboost1.62-all-dev libcurl4-openssl-dev libssl-dev

Build

# preparation

# clone repo and cd /to/repo/path
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release


# making

cmake --build .
sudo cmake --build . --target install
# or
sudo make && make install

Run (systemd)

sudo systemctl start wsserver.service
# or oldschool style:
sudo service wsserver start

Documentation (Doxygen)

chmod +x doc_gen.sh && ./doc_gen.sh

Then look for html doc inside docs/ directory

Configuring

Field Value type Default value Description
server object Common server configurations
endpoint string "/chat" Target websocket endpoint. Finally, address will loks like: ws://myserver/myendpoint
address string "*" (any) Server address. Leave asterisk (*) for apply any address, or set your server IP-address
port uint16 8085 Server incoming port. By default, is 8085. Don't forget to add rule for your iptables of firewalld rule: 8085/tcp
workers uint32 (system dependent) Number of threads for incoming connections. Recommended value - processor cores number. If wsserver can't determine number of cores, will set value to: 2
tmpDir string "/tmp" Temporary dir. Reserved, not used now.
useUniversalTime bool false Use local or universal time in messages (universal is UTC, local is system time).
secure object
secure.crtPath string "../certs/debug.crt" If server compiled with -DUSE_SSL, you must pass SSL cerificate file path.
secure.keyPath string "../certs/debug.key" If server compiled with -DUSE_SSL, you must pass SSL private key file path.
watchdog object
watchdog.enabled bool false Enables watchdog. Server will send every ~1 minute PING requests to clients, if they will not respond PONG or detected dangling connection, it will disconnected. Other case, if connection is unused watchdog.connectionLifetimeSeconds seconds, will disconnected too.
watchdog.connectionLifetimeSeconds long 600 Lifetime for inactive connection. Default: 10 minutes (600 seconds)
auth object
auth.type string "noauth" Authentication mode for websocket server. ype: noauth has no fields Be carefully! JS clients supports only basic and cookie auth. You can use oneOf auth type to combine different auth types for js and non-js clients
auth.type.basic object "basic" user: basic_username
value: basic_password
auth.type.bearer object "bearer" value: bearer_token
auth.type.header object "header" name: header_name
value: header_value
auth.type.cookie object "cookie" name: cookie_name
value: cookie_value
auth.type.oneOf object "oneOf" types: [...list of above auth objects...]
auth.type.allOf object "allOf" types: [...list of above auth objects...]
restApi object Rest API configuration.
enabled bool true Enable rest api server
address string "*" Server address. Leave asterisk (*) for apply any address, or set your server IP-address
port uint16 8092 Server incoming port. By default, is 8092. Don't forget to add rule for your iptables of firewalld rule: 8092/tcp
auth object Same configuration as server.auth (see above)
chat object Messaging configuration
enableUndeliveredQueue bool false Enable queue where server will store undelivered messages (by any reason)
message object
message.maxSize string "10M" Maximum message size.
If global payload size will be more than this value, server will disconnect client with error code 1009 (MESSAGE_TOO_BIG).
Value suffix must be "M" - megabytes or "K" - kilobytes
message.enableDeliveryStatus bool false Enable sending delivery status message to sender. When message will delivered to recipient, sender will receive a system message with type notification_received, informs about successfully delivery.

Notice: this option probably will be removed in the future, because it doesn't relates to sent messages by no means.
message.enableSendBack bool false Enable sending message back to the sender with the same payload (including timestamp and id)
event object Event notifier. Another words, its a message re-sender to custom target
enabled bool false Enable event notifier
enableRetry bool true Enable send retry when caused error (for example, postback-server responded non 200 http status)
retryIntervalSeconds uint32 10 Interval for retries (in seconds)
retryCount uint32 3 Maximum retries count
sendBotMessages bool false With this option, event notifier can ignore messages, that has come from Rest API method /send-message. What is a bot messages? Bot message is a message with sender = 0 (at least, for now)
maxParallelWorkers uint16 16 Maximum event notifier workers that sends messages to targets. Recommended workers count: not less than server workers count. Better value: server workers * 2, cause http request is longer than just tcp packet via WS.
Why http request? See below.
ignoreTypes string[] [] Ignored message types, that must be excluded from event notifier queue
targets object[] Event notifier targets configuration.For now, only available "postback" target. This target send to your server copy of message payload via http and json.
Available:
postback:
url: postback url, for example - http://mydomain/postback-url,
connectionTimeoutSeconds: maximum connection timeout to server. Big value can impact to performance and may require more event notifier workers. 10 seconds is most optimal (revealed by benchmarking). If 10 seconds is not enough, look at your server performance., auth: Same configuration as server.auth (see above)
targets[idx].type string "postback"
targets[idx].type string "redis" (available only with compile flag -DENABLE_REDIS_TARGET=On) see example.config.json

About

Scatter - Free and Open Source WebSocket standalone message server

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages