Git Product home page Git Product logo

socio's Introduction

Socio logo

Socio - A WebSocket Real-Time Communication (RTC) API framework. Realtime Front-end, Back-end reactivity.



This lets you write SQL in your frontend code, that automagically refreshes on all clients when a resource is changed on any (optionally) connected DB. Additionally, create any generic JS variables on your server to be realtime synced across all clients using "Server Props".

Agnostic of framework, build tool, server lib and SQL database. Requires Node.js >= 16 LTS.

Instalation ๐Ÿ”ง

In your project root dir:

npm i socio

Contains compiled JS files + TS type definition files.

How? โœจ

Socio is a "middle man" framework between your DB and browser clients. The SocioServer creates a WebSocket server on your backend, that can optionally be hooked up to any DB. The SocioClient sits on the browser (or backend with Deno) and communicates with your server through socios protocols and mechanisms. E.g. SocioClient.Query() or .Subscribe() with SQL strings and/or .SetProp() and .SubscribeProp() for generic data. Additionally, the server can also at any time push any data to any client(s), creating duplex real-time connections. Pretty much everything you'd need, including file transfer, is supported.

SQL injections and overall data safety? ๐Ÿ’‰

When using SQL, client-side JS source files contain only encrypted strings of your SQL. The used AES-256-GCM algorithm guarantees Confidentiality (cannot be read), Integrity (cannot be altered) and Authenticity (server can verify the author of the created cypher text). Dynamic data inserted as query parameters should be server-side sanitized by you as usual. In addition, all queries can use opt-in markers for authentification and table permissions requirements, that are managed by Socio Server for you. The encryption preproc step is done with the SocioSecurity class manually or automagically with the included Vite plugin SocioSecurityVitePlugin.

Code snippets ๐Ÿ“œ

Backend:

//TS server side. For SvelteKit, this can be in proj_root/src/hooks.server.ts . Check the Framework Demo for an example.
import { SocioServer } from 'socio/dist/core-server'; //Might need to put .js at the end.
import { SocioSecurity } from 'socio/dist/secure';
async function QueryWrap(client: SocioSession, id: id, sql: string, params: any):Promise<object> {
    //do whatever u need to run the sql on your DB and return its result. E.g. sequelize.query()
    //Or any other way you want to retrieve data, like reading a local txt etc.
    //sanatize dynamic params!
}

const socsec = new SocioSecurity({ secure_private_key: '...', logging:{verbose:true} }); //for decrypting incoming queries. This same key is used for encrypting the source files when you build and bundle them. Has to be the same in the Vite plugin.
const socserv = new SocioServer({ port: 3000 }, { db:{Query:QueryWrap}, socio_security: socsec, logging:{verbose:true} }); //creates localhost:3000 web socket server

Frontend:

//client side browser code.
import { SocioClient } from 'socio/dist/core-client'; //Might need to put .js at the end.
import { socio } from 'socio/dist/utils';
const sc = new SocioClient('ws://localhost:3000', {logging:{verbose:true}, name:'Main'}); //create as many as you like
await sc.ready(); //wait to establish the connection

//will recall the callback whenever the Users table is altered. Can also unsubscribe.
const sub_id = sc.Subscribe({sql:socio`SELECT * FROM Users;`}, (res:object) => {...});

//send a single query and wait for its result:
await sc.Query(socio`INSERT INTO Users (name, num) VALUES(:name, :num);`, {name:'bob', num:42}); //sanatize dynamic data yourself in QueryWrap!

//or work with general server side data:
let color = await sc.GetProp('color') as string; //the prop needs first to be created on the server and can be any json serializable object (including Map and Set)
sc.SubscribeProp('color', (c:string) => color = c); //can be unsubscribed
const res = await sc.SetProp('color', '#ffffff'); //this will rerun ^ the sub, if/when the server has set it, so no need to double your code everywhere!

Does it scale? โš–๏ธ

Currently the performance is neglegable for small projects. I havent stress tested yet, but I optimize my data structures and procedures. Current estimate is about 100 concurrent users should be a breeze on a cheap Linode server. I expect your backend DB to be set up properly with table indexing and caching.

According to this blog WebSockets are much more network traffic efficient than HTTP at scale.

Sportsmanship ๐Ÿค

The use of the Socio lib does not prohibit the use of standard HTTP technologies. Even better - socio server can be configured to run on your existing http webserver, like one that you'd create with express.js. Since WebSockets are established over HTTP, then take over with their own protocol. Though, seeing as they are different technologies, there are situations where you'd need to "stitch" your own solutions between the two, e.g. tracking sessions.

Caveats ๐Ÿšฉ

I cannot guarantee perfect safety of the query encryption. Neither can anything. You may use SocioServer hooks to double check the incoming data yourself for your peace of mind. However, I can guarantee this is safer than HTTP cookie based sessions (search "cookie spoofing").

You should be using WSS:// and HTTPS:// protocols for everything, so that the data is secure over the network. That's up to you and your server configuration.

Related lib and tech ๐Ÿ”—

  • WS Socio uses on the server
  • The WebSocket API Socio uses on the browser
  • NATS This has recently come to my attention. Together with the Node.js implementation of it and Nats.ws lib for running it on a browser, this technology seems to me like the future. If not Socio, you should use this imo.
  • Server-sent events API
  • Firebase Realtime Database serverless database. Google backed.
  • PocketBase serverless database.
  • SurrealDB serverless database.
  • RethinkDB distributed architecture serverless database.
  • SpacetimeDB realtime DB and web-server.
  • WebRTC standard another web protocol, but aimed at realtime binary data transmission like audio and video over UDP.
  • gRPC Google's Remote Procedure Call (RPC, another web protocol) framework, for interconnecting computers over a standardized data format between and inside data center machines and devices.
  • CRDT "Conflict-free Replicated Data Type" a data structure that simplifies distributed data storage systems and multi-user applications.
  • Yjs a general CRDT implementation for JS to power Live Collaboration webapps like editable documents.
  • RocketRPC an upcoming new project very similar to Socio.
  • tRPC allows you to easily build & consume fully typesafe APIs without schemas or code generation.

Name:

"Socio.js" comes from the latin verb "socio", which means to link or associate. Since this lib syncs your frontend and backend. Its also a play on words for "WebSockets" and "IO".

socio's People

Contributors

dependabot[bot] avatar rolands-laucis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

trasherdk fstfwd

socio's Issues

Current instructions to execute the basic demo not working.

npm run demo is not available, only dev & test.
And at the moment the library is not properly mapped in the client code, so the full path is required:
import { SocioClient } from './node_modules/socio/dist/core-client.js'

in place of './core-client.js'

Potential issues

Hi, just my two cents on what could be a potential security issue with your current model.
It is possible it has been addressed already, or it is taken care implicitly, I do not know the details of your implementation.

In principle, we can perform attacks on the secret key if we can guess some queries (known-plaintext attack).
Queries are quite low entropy as they are written in a regular language and their structure follows rationale principles.
This can be mitigated by adding random characters to them, which are later dropped in the back-end.

Interpolation in queries & strange behaviour with ' in place of "

At the moment, it seems like queries in this form are failing:

await sc.Query(
"INSERT INTO users:ch (name, num) VALUES(:name, :num);--socio",
{name: "Bob", num: 42, ch: "001a2ff"}
);

The interpolation of a table/view name is particularly useful when targetting custom views based on a source table, to split the update triggers and avoid propagating changes globally.

Also it seems like writing 'Bob' or "Bob" is not the same, as the first will fail, resulting in:
Error: the cipher text does not contain exactly 3 space seperated parts, therefor is invalid. [#cipher-text-invalid-format]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.