From 08195652b2b7261073d3aa4ec14a5f81659e31cd Mon Sep 17 00:00:00 2001 From: DrMxrcy <58747968+DrMxrcy@users.noreply.github.com> Date: Wed, 17 May 2023 15:20:54 -0400 Subject: [PATCH] Add Simplex SMP (#540) * Add SimpleX Chat * Update description.md * Update docker-compose.yml * Final Fixes and Instructions * Update description.md --- apps/simplex-smp/config.json | 26 +++++++++++++++++++++ apps/simplex-smp/docker-compose.yml | 22 ++++++++++++++++++ apps/simplex-smp/metadata/description.md | 28 +++++++++++++++++++++++ apps/simplex-smp/metadata/logo.jpg | Bin 0 -> 16780 bytes 4 files changed, 76 insertions(+) create mode 100644 apps/simplex-smp/config.json create mode 100644 apps/simplex-smp/docker-compose.yml create mode 100644 apps/simplex-smp/metadata/description.md create mode 100644 apps/simplex-smp/metadata/logo.jpg diff --git a/apps/simplex-smp/config.json b/apps/simplex-smp/config.json new file mode 100644 index 00000000..5232ec63 --- /dev/null +++ b/apps/simplex-smp/config.json @@ -0,0 +1,26 @@ +{ + "$schema": "../schema.json", + "name": "SimpleX SMP", + "port": 5223, + "available": true, + "exposable": true, + "no_gui": true, + "id": "simplex-smp", + "tipi_version": 1, + "version": "v5.1.0", + "categories": ["social"], + "description": "A reference implementation of the SimpleX Messaging Protocol for simplex queues over public networks.", + "short_desc": "A reference implementation of the SimpleX Messaging Protocol for simplex queues over public networks.", + "author": "Simplex Team", + "source": "https://github.com/simplex-chat/simplexmq", + "form_fields": [ + { + "type": "password", + "label": "SMP Password", + "max": 50, + "min": 3, + "required": true, + "env_variable": "SIMPLEX_SMP_PASSWORD" + } + ] +} diff --git a/apps/simplex-smp/docker-compose.yml b/apps/simplex-smp/docker-compose.yml new file mode 100644 index 00000000..c5be99dd --- /dev/null +++ b/apps/simplex-smp/docker-compose.yml @@ -0,0 +1,22 @@ +version: '3.9' +services: + simplex-smp: + image: simplexchat/smp-server:v5.1.0 + container_name: simplex-smp + volumes: + - ${APP_DATA_DIR}/data/simplex/logs:/var/opt/simplex:z + - ${APP_DATA_DIR}/data/simplex/config:/etc/opt/simplex:z + ports: + - ${APP_PORT}:5223 + environment: + - PASS=${SIMPLEX_SMP_PASSWORD} + - ADDR=${APP_DOMAIN} + networks: + - tipi_main_network + labels: + traefik.enable: ${APP_EXPOSED} + traefik.http.routers.simplex.rule: Host(`${APP_DOMAIN}`) + traefik.http.routers.simplex.entrypoints: websecure + traefik.http.routers.simplex.service: simplex + traefik.http.routers.simplex.tls.certresolver: myresolver + traefik.http.services.simplex.loadbalancer.server.port: 5223 diff --git a/apps/simplex-smp/metadata/description.md b/apps/simplex-smp/metadata/description.md new file mode 100644 index 00000000..67fedbb9 --- /dev/null +++ b/apps/simplex-smp/metadata/description.md @@ -0,0 +1,28 @@ +## Initial Setup + +To get the SMP Server Address + +1. SSH into your Tipi Server +2. Run `sudo docker logs simplex-smp 2>&1 | grep "Server address:" ` to find out the SMP Server Address. + +--- + +📢 SimpleXMQ v1 is released - with many security, privacy and efficiency improvements, new functionality - see [release notes](https://github.com/simplex-chat/simplexmq/releases/tag/v1.0.0). + +**Please note**: v1 is not backwards compatible, but it has the version negotiation built into all protocol layers for forwards compatibility of this version and backwards compatibility of the future versions, that will be backwards compatible for at least two versions back. + +If you have a server deployed please deploy a new server to a new host and retire the previous version once it is no longer used. + +## [](https://github.com/simplex-chat/simplexmq#message-broker-for-unidirectional-simplex-queues)Message broker for unidirectional (simplex) queues + +SimpleXMQ is a message broker for managing message queues and sending messages over public network. It consists of SMP server, SMP client library and SMP agent that implement [SMP protocol](https://github.com/simplex-chat/simplexmq/blob/stable/protocol/simplex-messaging.md) for client-server communication and [SMP agent protocol](https://github.com/simplex-chat/simplexmq/blob/stable/protocol/agent-protocol.md) to manage duplex connections via simplex queues on multiple SMP servers. + +SMP protocol is inspired by [Redis serialization protocol](https://redis.io/topics/protocol), but it is much simpler - it currently has only 10 client commands and 8 server responses. + +SimpleXMQ is implemented in Haskell - it benefits from robust software transactional memory (STM) and concurrency primitives that Haskell provides. + +## [](https://github.com/simplex-chat/simplexmq#simplexmq-roadmap)SimpleXMQ roadmap + +- SimpleX service protocol and application template - to enable users building services and chat bots that work over SimpleX protocol stack. The first such service will be a notification service for a mobile app. +- SMP queue redundancy and rotation in SMP agent connections. +- SMP agents synchronization to share connections and messages between multiple agents (it would allow using multiple devices for [simplex-chat](https://github.com/simplex-chat/simplex-chat)). \ No newline at end of file diff --git a/apps/simplex-smp/metadata/logo.jpg b/apps/simplex-smp/metadata/logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c1214707c4588daa91079fc76723466a666e7c01 GIT binary patch literal 16780 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 TnFEu#k&b}|5S$PG{_=kSNkwkD literal 0 HcmV?d00001