SSH to WebSockets Bridge

Related tags

DevOps Tools wssh
Overview

wssh

wssh is a SSH to WebSockets Bridge that lets you invoke a remote shell using nothing but HTTP.

The client connecting to wssh doesn't need to speak the SSH protocol - rather, the SSH connection is terminated at the bridge level and the pty is wrapper through a thin layer of JSON and sent back to the client.

This means you can implement a WSSH client in just a few lines of code, even for a web browser.

Usage

Even though wssh primary purpose is to be used as a library in your applications, it ships with two command line tools: wsshd (the server) and wssh (the client).

$ wsshd 
wsshd/0.1.0 running on 0.0.0.0:5000
$ wssh aluzzardi@mba -p
Password: 
Last login: Mon Jul 23 23:20:27 2012 from localhost
aluzzardi@mba:~$ 

Web Interface

wsshd provides a web interface giving you access to a Javascript client

wssh: shell

wssh: vim

Creating your own server

wsshd is just a simple server implementation to demonstrate the wssh library.

You can actually integrate wssh into your own Python web application in order to provide terminal access. For instance, you may want to provide shell access to clients authenticated through OAuth to a special user account. The client doesn't need to know where the SSH server is located nor its credentials.

An example using the Flask framework is provided in examples/flask_server.py

Creating your own client

Beside the command line tool, wssh comes bundled with both a Python and a Javascript client library for the wssh bridge.

There are examples available in the examples/ directory for both languages.

You can write your own library in another language in just a few lines of code.

Comments
  • Unknown license

    Unknown license

    Hi aluzzardi

    I just started a project based on your wssh implementation. But for now i stopped working on it because i noticed that i don't have a clue about the license of wssh. Would be very nice if you could take a license note on wssh.

    Thanks RedDog

    opened by RedDog99 3
  • Fixup and expose command usage

    Fixup and expose command usage

    Hi,

    I needed to execute a command directly, thought I will need to hack the implementation, but found that you already thought of it :)

    I found one issue that may be a typo, and also exposed the usage so other people know it is supported.

    Thanks!

    opened by alonbl 2
  • fixed VIM freezes & support UTF-8

    fixed VIM freezes & support UTF-8

    thanks,aluzzardi. sorry everyboy for my english.

    diff --git a/wssh/server.py b/wssh/server.py
    index 17a4965..b334477 100644
    --- a/wssh/server.py
    +++ b/wssh/server.py
    @@ -118,19 +118,26 @@ class WSSHBridge(object):
                             data['resize'].get('width', 80),
                             data['resize'].get('height', 24))
                     if 'data' in data:
    -                    channel.send(data['data'])
    +                    channel.send(data['data'].encode('utf-8'))
             finally:
                 self.close()
    
         def _forward_outbound(self, channel):
             """ Forward outbound traffic (ssh -> websockets) """
             try:
    +            data = ''
                 while True:
                     wait_read(channel.fileno())
    -                data = channel.recv(1024)
    -                if not len(data):
    +                recv = channel.recv(1024)
    +                if not len(recv):
                         return
    -                self._websocket.send(json.dumps({'data': data}))
    +                
    +                data += recv
    +                try:
    +                    self._websocket.send(json.dumps({'data':data}))
    +                    data = ''
    +                except UnicodeDecodeError:
    +                    pass
             finally:
                 self.close()
    
    diff --git a/wssh/static/term.js b/wssh/static/term.js
    index 9489334..20883bf 100644
    --- a/wssh/static/term.js
    +++ b/wssh/static/term.js
    @@ -129,9 +129,10 @@ function Terminal(cols, rows, handler) {
    
       this.cols = cols || Terminal.geometry[0];
       this.rows = rows || Terminal.geometry[1];
    -
    -  if (handler) {
    -    this.on('data', handler);
    +  this.handler = handler;
    +  
    +  if (this.handler) {
    +    this.on('data', this.handler);
       }
    
       this.ybase = 0;
    @@ -2432,7 +2433,7 @@ Terminal.prototype.reverseIndex = function() {
    
     // ESC c Full Reset (RIS).
     Terminal.prototype.reset = function() {
    -  Terminal.call(this, this.cols, this.rows);
    +  Terminal.call(this, this.cols, this.rows, this.handler);
       this.refresh(0, this.rows - 1);
     };
    
    
    opened by zlhgo 1
  • fixes `wssd -p` argument and more

    fixes `wssd -p` argument and more

    fixes some bugs:

    • could not change port any other except of 5000 caused by --port argument did not parsed as int.
    • term.js did not loaded properly caused by github serves raw files only in text/html
    opened by comfuture 0
  • HI,aluzzardi

    HI,aluzzardi

    When I run wsshd in the Terminal,it throw error

    File "/usr/local/lib/python2.7/dist-packages/wssh-0.1.0-py2.7.egg/EGG-INFO/scripts/wsshd", line 65, in from geventwebsocket import WebSocketHandler

    ImportError: cannot import name WebSocketHandler

    I view the page https://pypi.python.org/pypi/gevent-websocket/ I think the script wssd line 65 should change from geventwebsocket import WebSocketHandler to from geventwebsocket.handler import WebSocketHandler

    opened by azzgo 0
  • the github can not access

    the github can not access

    <script type="application/javascript" src="{{url_for('static', filename='jquery.min.js}}}">
        </script>
        <script type="application/javascript" src="{{url_for('static', filename='term.js')}}">
        </script
    
    opened by zhausong 0
  • Chinese Support Abnormality

    Chinese Support Abnormality

    When text contains chinese charactor, wssh will shutdown with situation like blow. The wssd logs show nothing, who can help me? thanks

    log: [root@paasm1 ~]# more /test/aaa.txt 关于大胜靠德卡和扩大后方可速度快发送会计法 发生发大水 发生的 房东说Connection Reset By Peer

    opened by wangyao2016 0
  • Decode to UTF-8 before loading the JSON

    Decode to UTF-8 before loading the JSON

    Hi!

    If the data is not being encoded to UTF-8 the bridge closes the connection because an unexpected exception. This could be easily reproduced sending {"data":"ñ"} via websocket.

    opened by atrioinc 0
  • How Web socket are send from web browser.

    How Web socket are send from web browser.

    Hi ,

    Can anyone clarify below doubt:--

    1. How browser is creating web socket and sending it?
    2. How request.environ.get('wsgi.websocket') receive web socket?

    If anyone can clarify it will be great help

    opened by Manish-Savanur-ML 1
  • TypeError: from_buffer() cannot return the address of the raw string within a str or unicode or bytearray object

    TypeError: from_buffer() cannot return the address of the raw string within a str or unicode or bytearray object

    After start wssd on linux terminal,login linux by browser, and click the connect button, below appeared:

    Error: from_buffer() cannot return the address of the raw string within a str or unicode or bytearray object
    Connection Reset By peer.

    logs:

    DEBUG in wsshd [/usr/lib/python2.7/site-packages/wssh-0.1.0-py2.7.egg/EGG-INFO/scripts/wsshd:27]: 192.168.1.115 -> root@localhost: [interactive shell]


    ERROR in wsshd [/usr/lib/python2.7/site-packages/wssh-0.1.0-py2.7.egg/EGG-INFO/scripts/wsshd:47]: Error while connecting to localhost: from_buffer() cannot return the address of the raw string within a str or unicode or bytearray object

    Traceback (most recent call last): File "/usr/lib/python2.7/site-packages/wssh-0.1.0-py2.7.egg/EGG-INFO/scripts/wsshd", line 44, in connect allow_agent=app.config.get('WSSH_ALLOW_SSH_AGENT', False)) File "/usr/lib/python2.7/site-packages/wssh-0.1.0-py2.7.egg/wssh/server.py", line 98, in open look_for_keys=False) File "/usr/lib/python2.7/site-packages/paramiko/client.py", line 380, in connect look_for_keys, gss_auth, gss_kex, gss_deleg_creds, gss_host) File "/usr/lib/python2.7/site-packages/paramiko/client.py", line 608, in _auth self._transport.auth_password(username, password) File "/usr/lib/python2.7/site-packages/paramiko/transport.py", line 1266, in auth_password self.auth_handler.auth_password(username, password, my_event) File "/usr/lib/python2.7/site-packages/paramiko/auth_handler.py", line 107, in auth_password self._request_auth() File "/usr/lib/python2.7/site-packages/paramiko/auth_handler.py", line 158, in _request_auth self.transport._send_message(m) File "/usr/lib/python2.7/site-packages/paramiko/transport.py", line 1587, in _send_message self.packetizer.send_message(data) File "/usr/lib/python2.7/site-packages/paramiko/packet.py", line 360, in send_message out = self.__block_engine_out.update(packet) File "/usr/lib64/python2.7/site-packages/cryptography/hazmat/primitives/ciphers/base.py", line 149, in update return self._ctx.update(data) File "/usr/lib64/python2.7/site-packages/cryptography/hazmat/backends/openssl/ciphers.py", line 120, in update n = self.update_into(data, buf) File "/usr/lib64/python2.7/site-packages/cryptography/hazmat/backends/openssl/ciphers.py", line 131, in update_into "unsigned char *", self._backend._ffi.from_buffer(buf) TypeError: from_buffer() cannot return the address of the raw string within a str or unicode or bytearray object

    DEBUG in wsshd [/usr/lib/python2.7/site-packages/wssh-0.1.0-py2.7.egg/EGG-INFO/scripts/wsshd:27]: 192.168.1.115 -> [email protected]: [interactive shell]


    ERROR in wsshd [/usr/lib/python2.7/site-packages/wssh-0.1.0-py2.7.egg/EGG-INFO/scripts/wsshd:47]: Error while connecting to 127.0.0.1: from_buffer() cannot return the address of the raw string within a str or unicode or bytearray object

    Traceback (most recent call last): File "/usr/lib/python2.7/site-packages/wssh-0.1.0-py2.7.egg/EGG-INFO/scripts/wsshd", line 44, in connect allow_agent=app.config.get('WSSH_ALLOW_SSH_AGENT', False)) File "/usr/lib/python2.7/site-packages/wssh-0.1.0-py2.7.egg/wssh/server.py", line 98, in open look_for_keys=False) File "/usr/lib/python2.7/site-packages/paramiko/client.py", line 380, in connect look_for_keys, gss_auth, gss_kex, gss_deleg_creds, gss_host) File "/usr/lib/python2.7/site-packages/paramiko/client.py", line 608, in _auth self._transport.auth_password(username, password) File "/usr/lib/python2.7/site-packages/paramiko/transport.py", line 1266, in auth_password self.auth_handler.auth_password(username, password, my_event) File "/usr/lib/python2.7/site-packages/paramiko/auth_handler.py", line 107, in auth_password self._request_auth() File "/usr/lib/python2.7/site-packages/paramiko/auth_handler.py", line 158, in _request_auth self.transport._send_message(m) File "/usr/lib/python2.7/site-packages/paramiko/transport.py", line 1587, in _send_message self.packetizer.send_message(data) File "/usr/lib/python2.7/site-packages/paramiko/packet.py", line 360, in send_message out = self.__block_engine_out.update(packet) File "/usr/lib64/python2.7/site-packages/cryptography/hazmat/primitives/ciphers/base.py", line 149, in update return self._ctx.update(data) File "/usr/lib64/python2.7/site-packages/cryptography/hazmat/backends/openssl/ciphers.py", line 120, in update n = self.update_into(data, buf) File "/usr/lib64/python2.7/site-packages/cryptography/hazmat/backends/openssl/ciphers.py", line 131, in update_into "unsigned char *", self._backend._ffi.from_buffer(buf) TypeError: from_buffer() cannot return the address of the raw string within a str or unicode or bytearray object

    DEBUG in wsshd [/usr/lib/python2.7/site-packages/wssh-0.1.0-py2.7.egg/EGG-INFO/scripts/wsshd:27]: 192.168.1.115 -> aaronwtl@localhost: [interactive shell]


    ERROR in wsshd [/usr/lib/python2.7/site-packages/wssh-0.1.0-py2.7.egg/EGG-INFO/scripts/wsshd:47]: Error while connecting to localhost: from_buffer() cannot return the address of the raw string within a str or unicode or bytearray object

    Traceback (most recent call last): File "/usr/lib/python2.7/site-packages/wssh-0.1.0-py2.7.egg/EGG-INFO/scripts/wsshd", line 44, in connect allow_agent=app.config.get('WSSH_ALLOW_SSH_AGENT', False)) File "/usr/lib/python2.7/site-packages/wssh-0.1.0-py2.7.egg/wssh/server.py", line 98, in open look_for_keys=False) File "/usr/lib/python2.7/site-packages/paramiko/client.py", line 380, in connect look_for_keys, gss_auth, gss_kex, gss_deleg_creds, gss_host) File "/usr/lib/python2.7/site-packages/paramiko/client.py", line 608, in _auth self._transport.auth_password(username, password) File "/usr/lib/python2.7/site-packages/paramiko/transport.py", line 1266, in auth_password self.auth_handler.auth_password(username, password, my_event) File "/usr/lib/python2.7/site-packages/paramiko/auth_handler.py", line 107, in auth_password self._request_auth() File "/usr/lib/python2.7/site-packages/paramiko/auth_handler.py", line 158, in _request_auth self.transport._send_message(m) File "/usr/lib/python2.7/site-packages/paramiko/transport.py", line 1587, in _send_message self.packetizer.send_message(data) File "/usr/lib/python2.7/site-packages/paramiko/packet.py", line 360, in send_message out = self.__block_engine_out.update(packet) File "/usr/lib64/python2.7/site-packages/cryptography/hazmat/primitives/ciphers/base.py", line 149, in update return self._ctx.update(data) File "/usr/lib64/python2.7/site-packages/cryptography/hazmat/backends/openssl/ciphers.py", line 120, in update n = self.update_into(data, buf) File "/usr/lib64/python2.7/site-packages/cryptography/hazmat/backends/openssl/ciphers.py", line 131, in update_into "unsigned char *", self._backend._ffi.from_buffer(buf) TypeError: from_buffer() cannot return the address of the raw string within a str or unicode or bytearray object

    DEBUG in wsshd [/usr/lib/python2.7/site-packages/wssh-0.1.0-py2.7.egg/EGG-INFO/scripts/wsshd:27]: 192.168.1.115 -> aaronwtl@localhost: [interactive shell]


    ERROR in wsshd [/usr/lib/python2.7/site-packages/wssh-0.1.0-py2.7.egg/EGG-INFO/scripts/wsshd:47]: Error while connecting to localhost: from_buffer() cannot return the address of the raw string within a str or unicode or bytearray object

    Traceback (most recent call last): File "/usr/lib/python2.7/site-packages/wssh-0.1.0-py2.7.egg/EGG-INFO/scripts/wsshd", line 44, in connect allow_agent=app.config.get('WSSH_ALLOW_SSH_AGENT', False)) File "/usr/lib/python2.7/site-packages/wssh-0.1.0-py2.7.egg/wssh/server.py", line 98, in open look_for_keys=False) File "/usr/lib/python2.7/site-packages/paramiko/client.py", line 380, in connect look_for_keys, gss_auth, gss_kex, gss_deleg_creds, gss_host) File "/usr/lib/python2.7/site-packages/paramiko/client.py", line 608, in _auth self._transport.auth_password(username, password) File "/usr/lib/python2.7/site-packages/paramiko/transport.py", line 1266, in auth_password self.auth_handler.auth_password(username, password, my_event) File "/usr/lib/python2.7/site-packages/paramiko/auth_handler.py", line 107, in auth_password self._request_auth() File "/usr/lib/python2.7/site-packages/paramiko/auth_handler.py", line 158, in _request_auth self.transport._send_message(m) File "/usr/lib/python2.7/site-packages/paramiko/transport.py", line 1587, in _send_message self.packetizer.send_message(data) File "/usr/lib/python2.7/site-packages/paramiko/packet.py", line 360, in send_message out = self.__block_engine_out.update(packet) File "/usr/lib64/python2.7/site-packages/cryptography/hazmat/primitives/ciphers/base.py", line 149, in update return self._ctx.update(data) File "/usr/lib64/python2.7/site-packages/cryptography/hazmat/backends/openssl/ciphers.py", line 120, in update n = self.update_into(data, buf) File "/usr/lib64/python2.7/site-packages/cryptography/hazmat/backends/openssl/ciphers.py", line 131, in update_into "unsigned char *", self._backend._ffi.from_buffer(buf) TypeError: from_buffer() cannot return the address of the raw string within a str or unicode or bytearray object ^CKeyboardInterrupt Sun Jan 28 10:07:37 2018 [root@localhost wssh]# wsshd wsshd/0.1.0 running on 0.0.0.0:5000

    DEBUG in wsshd [/usr/lib/python2.7/site-packages/wssh-0.1.0-py2.7.egg/EGG-INFO/scripts/wsshd:27]: 192.168.1.115 -> aaronwtl@localhost: [interactive shell]


    ERROR in wsshd [/usr/lib/python2.7/site-packages/wssh-0.1.0-py2.7.egg/EGG-INFO/scripts/wsshd:47]: Error while connecting to localhost: from_buffer() cannot return the address of the raw string within a str or unicode or bytearray object

    Traceback (most recent call last): File "/usr/lib/python2.7/site-packages/wssh-0.1.0-py2.7.egg/EGG-INFO/scripts/wsshd", line 44, in connect allow_agent=app.config.get('WSSH_ALLOW_SSH_AGENT', False)) File "/usr/lib/python2.7/site-packages/wssh-0.1.0-py2.7.egg/wssh/server.py", line 98, in open look_for_keys=False) File "/usr/lib/python2.7/site-packages/paramiko/client.py", line 380, in connect look_for_keys, gss_auth, gss_kex, gss_deleg_creds, gss_host) File "/usr/lib/python2.7/site-packages/paramiko/client.py", line 608, in _auth self._transport.auth_password(username, password) File "/usr/lib/python2.7/site-packages/paramiko/transport.py", line 1266, in auth_password self.auth_handler.auth_password(username, password, my_event) File "/usr/lib/python2.7/site-packages/paramiko/auth_handler.py", line 107, in auth_password self._request_auth() File "/usr/lib/python2.7/site-packages/paramiko/auth_handler.py", line 158, in _request_auth self.transport._send_message(m) File "/usr/lib/python2.7/site-packages/paramiko/transport.py", line 1587, in _send_message self.packetizer.send_message(data) File "/usr/lib/python2.7/site-packages/paramiko/packet.py", line 360, in send_message out = self.__block_engine_out.update(packet) File "/usr/lib64/python2.7/site-packages/cryptography/hazmat/primitives/ciphers/base.py", line 149, in update return self._ctx.update(data) File "/usr/lib64/python2.7/site-packages/cryptography/hazmat/backends/openssl/ciphers.py", line 120, in update n = self.update_into(data, buf) File "/usr/lib64/python2.7/site-packages/cryptography/hazmat/backends/openssl/ciphers.py", line 131, in update_into "unsigned char *", self._backend._ffi.from_buffer(buf) TypeError: from_buffer() cannot return the address of the raw string within a str or unicode or bytearray object

    opened by Ericwtl 1
  • Can not connect linux on browser

    Can not connect linux on browser

    After start wssd on linux terminal,I connect the linux terminal on browser,but when I clikc the connect button on screen,the next screen shows: “ Error: 'type' object is not iterable
    Connection Reset By Peer ” And the sshd server log on linux terminal shows: “ ivanli@ubuntu:~$ wsshd wsshd/0.1.0 running on 0.0.0.0:5000

    DEBUG in wsshd [/usr/local/lib/python2.7/dist-packages/wssh-0.1.0-py2.7.egg/EGG-INFO/scripts/wsshd:27]: 127.0.0.1 -> ivanli@ubuntu: [interactive shell]

    No handlers could be found for logger "paramiko.transport"

    ERROR in wsshd [/usr/local/lib/python2.7/dist-packages/wssh-0.1.0-py2.7.egg/EGG-INFO/scripts/wsshd:47]: Error while connecting to ubuntu: 'type' object is not iterable

    Traceback (most recent call last): File "/usr/local/lib/python2.7/dist-packages/wssh-0.1.0-py2.7.egg/EGG-INFO/scripts/wsshd", line 44, in connect allow_agent=app.config.get('WSSH_ALLOW_SSH_AGENT', False)) File "/usr/local/lib/python2.7/dist-packages/wssh-0.1.0-py2.7.egg/wssh/server.py", line 98, in open look_for_keys=False) File "/usr/local/lib/python2.7/dist-packages/paramiko/client.py", line 392, in connect t.start_client(timeout=timeout) File "/usr/local/lib/python2.7/dist-packages/paramiko/transport.py", line 545, in start_client raise e TypeError: 'type' object is not iterable ” Please help me solve the problem, 3q~

    opened by ivanli1990 0
Owner
Andrea Luzzardi
Andrea Luzzardi
SSH tunnels to remote server.

Author: Pahaz Repo: https://github.com/pahaz/sshtunnel/ Inspired by https://github.com/jmagnusson/bgtunnel, which doesn't work on Windows. See also: h

Pavel White 1k Dec 28, 2022
Manage your SSH like a boss.

--- storm is a command line tool to manage your ssh connections. features adding, editing, deleting, listing, searching across your SSHConfig. command

Emre Yılmaz 3.9k Jan 3, 2023
Asynchronous parallel SSH client library.

parallel-ssh Asynchronous parallel SSH client library. Run SSH commands over many - hundreds/hundreds of thousands - number of servers asynchronously

null 1.1k Dec 31, 2022
Simple ssh overlay for easy, remote server management written in Python GTK with paramiko

Simple "ssh" overlay for easy, remote server management written in Python GTK with paramiko

kłapouch 3 May 1, 2022
SSH-Restricted deploys an SSH compliance rule (AWS Config) with auto-remediation via AWS Lambda if SSH access is public.

SSH-Restricted SSH-Restricted deploys an SSH compliance rule with auto-remediation via AWS Lambda if SSH access is public. SSH-Auto-Restricted checks

Adrian Hornsby 30 Nov 8, 2022
A fast and durable Pub/Sub channel over Websockets. FastAPI + WebSockets + PubSub == ⚡ 💪 ❤️

⚡ ??️ FastAPI Websocket Pub/Sub A fast and durable Pub/Sub channel over Websockets. The easiest way to create a live publish / subscribe multi-cast ov

null 8 Dec 6, 2022
Burgeramt-appointments-websockets - Fetch Bürgeramt appointments and broadcast them via websockets

Bürgeramt appointment finder This server looks for Bürgeramt appointment every f

null 74 Dec 19, 2022
2022-bridge - Example code belonging to the Bridge pattern video

Let's Take The Bridge Pattern To The Next Level This video covers how the bridge

null 11 Jun 14, 2022
An improbable web debugger through WebSockets

wdb - Web Debugger Description wdb is a full featured web debugger based on a client-server architecture. The wdb server which is responsible of manag

Kozea 1.6k Dec 9, 2022
Elegant WebSockets for your Flask apps.

Flask-Sockets Elegant WebSockets for your Flask apps. Simple usage of route decorator: from flask import Flask from flask_sockets import Sockets app

Heroku Python Team 1.7k Dec 26, 2022
An improbable web debugger through WebSockets

wdb - Web Debugger Description wdb is a full featured web debugger based on a client-server architecture. The wdb server which is responsible of manag

Kozea 1.6k Dec 9, 2022
Chat app for Django, powered by Django Channels, Websockets & Asyncio

Django Private Chat2 New and improved https://github.com/Bearle/django-private-chat Chat app for Django, powered by Django Channels, Websockets & Asyn

Bearle 205 Dec 30, 2022
🚀 An asynchronous python API wrapper meant to replace discord.py - Snappy discord api wrapper written with aiohttp & websockets

Pincer An asynchronous python API wrapper meant to replace discord.py ❗ The package is currently within the planning phase ?? Links |Join the discord

Pincer 125 Dec 26, 2022
WebSocket implementation in Python built on top of websockets python library. Similar to Node.js's ws.

ws WebSocket implementation in Python built on top of websockets python library. Similar to Node.js's ws. Basic usage. server.py import ws server = w

AceExpert 7 Jun 27, 2022
Library for easily creating and managing websockets.

Documentation coming in version 0.1.4 GitHub PyPI Discord Features Easy to use with object oriented syntax. Intellisense support with typehints and do

ZeroIntensity 0 Aug 27, 2022
Connects microservices through a mesh of websockets

WebMesh WebMesh is a WebSocket based communication library for microservices. It uses a WebSocket server based on wsproto that distributes clients on

Charles Smith 9 Apr 29, 2022
Client library for relay - a service for relaying server side messages to the client side browsers via websockets.

Client library for relay - a service for relaying server side messages to the client side browsers via websockets.

getme 1 Nov 10, 2021
A Security Tool for Enumerating WebSockets

STEWS: Security Testing and Enumeration of WebSockets STEWS is a tool suite for security testing of WebSockets This research was first presented at OW

null 175 Jan 1, 2023
An IPC based on Websockets, fast, stable, and reliable

winerp An IPC based on Websockets. Fast, Stable, and easy-to-use, for inter-communication between your processes or discord.py bots. Key Features Fast

Black Thunder 5 Aug 9, 2022