All Projects → akoidan → Pychat

akoidan / Pychat

Licence: mit
webchat via WebSockets/WebRTC that allows messaging/video call/screen sharing

Programming Languages

javascript
184084 projects - #8 most used programming language
python
139335 projects - #7 most used programming language
typescript
32286 projects

Projects that are alternatives of or similar to Pychat

Laravel Vue
运用laravel5.4 + vue2.0 + elementui
Stars: ✭ 276 (+81.58%)
Mutual labels:  webpack, mysql, redis
Python Spider
豆瓣电影top250、斗鱼爬取json数据以及爬取美女图片、淘宝、有缘、CrawlSpider爬取红娘网相亲人的部分基本信息以及红娘网分布式爬取和存储redis、爬虫小demo、Selenium、爬取多点、django开发接口、爬取有缘网信息、模拟知乎登录、模拟github登录、模拟图虫网登录、爬取多点商城整站数据、爬取微信公众号历史文章、爬取微信群或者微信好友分享的文章、itchat监听指定微信公众号分享的文章
Stars: ✭ 615 (+304.61%)
Mutual labels:  mysql, redis, django
React Redux Chat
🔥🔥react+redux-chat 模仿实现PC微信聊天系统。
Stars: ✭ 308 (+102.63%)
Mutual labels:  webpack, websockets, sass
Django instagram
Photo sharing social media site built with Python/Django. Based on Instagram's design.
Stars: ✭ 165 (+8.55%)
Mutual labels:  redis, django, websockets
Laravel Blog
Laravel 8.0 blog application with Vue.js, Homestead, Horizon, Telescope and Pusher
Stars: ✭ 1,248 (+721.05%)
Mutual labels:  webpack, redis, websockets
React Cordova Boilerplate
TodoMVC example for react with development tools to build a cordova application
Stars: ✭ 206 (+35.53%)
Mutual labels:  webpack, cordova, sass
Autoops
linux资产管理,cmdb,django, webssh,运维管理平台,数据库操作平台 本项目已停止开发!因长时间未对代码进行维护,可能会造成项目在不同环境上无法部署、运行BUG等问题,请知晓!项目仅供参考!
Stars: ✭ 340 (+123.68%)
Mutual labels:  mysql, django, tornado
Docker Django Webpack Skeleton
Django Skeleton W/ Docker Dev & Production W/ Webpack 2 W/ BabelJS W/ Sass W/ PostgreSQL
Stars: ✭ 191 (+25.66%)
Mutual labels:  webpack, django, sass
Django Channels React Multiplayer
turn based strategy game using django channels, redux, and react hooks
Stars: ✭ 52 (-65.79%)
Mutual labels:  redis, django, websockets
Funpyspidersearchengine
Word2vec 千人千面 个性化搜索 + Scrapy2.3.0(爬取数据) + ElasticSearch7.9.1(存储数据并提供对外Restful API) + Django3.1.1 搜索
Stars: ✭ 782 (+414.47%)
Mutual labels:  mysql, redis, django
Doudizhu
html5 斗地主游戏
Stars: ✭ 323 (+112.5%)
Mutual labels:  mysql, websockets, tornado
Instacam
Instant canvas video
Stars: ✭ 106 (-30.26%)
Mutual labels:  webpack, webrtc, canvas
Nice Front End Tutorial
🌍 Constantly updated front-end resources, tutorials, opinions(与时俱进版前端资源,教程和意见。)
Stars: ✭ 755 (+396.71%)
Mutual labels:  webpack, redis, webassembly
Docker Django Example
A production ready example Django app that's using Docker and Docker Compose.
Stars: ✭ 86 (-43.42%)
Mutual labels:  webpack, redis, django
Dailyfresh
Django-天天生鲜电商学习项目
Stars: ✭ 127 (-16.45%)
Mutual labels:  mysql, redis, django
Echo
🦄 开源社区系统:基于 SpringBoot + MyBatis + MySQL + Redis + Kafka + Elasticsearch + Spring Security + ... 并提供详细的开发文档和配套教程。包含帖子、评论、私信、系统通知、点赞、关注、搜索、用户设置、数据统计等模块。
Stars: ✭ 129 (-15.13%)
Mutual labels:  mysql, redis
Roothub
使用 SSM 和 MySQL 开发的论坛系统
Stars: ✭ 131 (-13.82%)
Mutual labels:  mysql, redis
Dev Toolkit
Universal Development Toolkit for Javascript People
Stars: ✭ 134 (-11.84%)
Mutual labels:  webpack, sass
Nes Rust
NES emulator written in Rust + WASM
Stars: ✭ 141 (-7.24%)
Mutual labels:  webrtc, webassembly
App Turbo
A framework based on tornado for easier development, scaling up and maintenance
Stars: ✭ 131 (-13.82%)
Mutual labels:  mysql, tornado

Docker Cloud Build Status Docker Cloud Build Status Scrutinizer Code Quality Codacy BadgeCode Health Upload Frontend pychat.org Refresh backend pychat.org

Live demo: pychat.org, video

Table of contents

About

Pychat is an opensource absolutely free communcation tool targeted for a copmany use. It's created as alternative to Slack/Discord. See the table below to understand its key features.

When should I use pychat

Pychat Slack Skype Telegram Viber Discord
Open Source + - - - - -
Free + +/- +/- + +/- +/-
Screen sharing + + - - - +
Stream drawing + - - - - -
Syntax highlight + - - - - +
Only company users + + - - - +
Audio/Video conference + + + + - +
Can run on your server + - - - - -
Audio/Video messages + - - + + -
P2P file sharing + - - - - -
P2P messaging + - - - - -
Message read status + - + + + -
Tagging user + + - + + +
Message threads + + - - - -
PWA (works w/o lan) + - - - - -
Desktop client +/- + + + +/- +
Mobile client +/- + + + + +
3rd-party plugins - + - - - +

I would personally use discord or slack as a company chat. They are built and maintained by thousands of people rather than a single person. BUT wait!!! There're some key factors of picking pychat over others:

  1. Being opensource. If you need to add some custom tool or feature, you will never able to do this with any other messanger. Slack and discord provides plugins but they are still limited.
  2. Being absolutely free. You don't need to pay anything to use or setup pychat at all. You can host pychat on low-end hardware like Raspberry Pi which costs under 50$ and will easily handle thousands of active users. Slack and Discord will charge you for the set of features you need now or WILL need in the future. Telegram/Skype/Viber and etc are not corporate chats and they lack a lot of features and there're people all over the world which could accidentaly be invited to your group.
  3. Security. All of the chats above are SAAS solutions, but not Pychat! Remember wHen you chose any messangers, all of your communication is stored on external hard drive which is always less secure. Some messangers like viber or whatsapp backup do not store messages but rather backup history to your google driver. But that often leads to holes in history and broken search. Also only pychat features p2p file sharing. Do you still use messangers to echange ssh keys or any other secure files? Never store them on the server! Only with pychat you can send file directly to another person ommiting persisting it on the server.
  4. You just feel enthusiastic for bleeding-edge opensource projects.

How to host pychat

Run test docker image

Please don't use this build for production, as it uses debug ssl certificate, lacks a few features and all files are located inside of container, meaning you will lose all data on container destroy.

  • Download and run image:
docker run -tp 443:443 deathangel908/pychat-test

Run prod docker image

Please run each step very carefully. Do not skip editing files, reading comments or any instructions. This may lead to bugs in the future.

  • Ssl is required for webrtc (to make calls) and secure connection. Put your ssl certificates in the current directory: server.key and certificate.crt. If you don't own a domain you can create self-signed certificates with command below, with self-signed certificate browser will warn users with broken ssl.
openssl req -nodes -new -x509 -keyout server.key -out certificate.crt -days 3650
docker volume create pychat_data
containerid=`docker container create --name dummy -v pychat_data:/data hello-world`
docker cp settings.py dummy:/data/settings.py
docker cp production.json dummy:/data/production.json
docker cp turnserver.conf dummy:/data/turnserver.conf
docker cp certificate.crt dummy:/data/certificate.crt
docker cp server.key dummy:/data/server.key
docker rm dummy

If you need to edit files inside container you can use

docker run -i -t -v pychat_data:/tmp -it alpine /bin/sh
  • Run image with:
docker run -t -v pychat_data:/data -p 443:443 -p 3478:3478 deathangel908/pychat

Native setup

If you don't or unable to run docker you can alway do the setup w/o it. You definitely spend more time, so I would recommend to use docker if possible. But if you're still sure, here's the setup for cent-os/archlinux based system:

  1. For production I would recommend to clone repository to /srv/http/pychat. If you want to close the project into a different directory, replace all absolute paths in config files. You can use download_content.sh rename_root_directory to do that.
  2. Install packages:
    • For archlinux follow Install OS packages, add add these ones: pacman -S postfix gcc jansson.
    • For centos use add alias yum="python2 $(which yum)" to /etc/bashrc if you use python3. And then install that packages yum install python34u, python34u-pip, redis, mysql-server, mysql-devel, postfix, mailx
    • If you use another OS, try to figure out from Install OS packages guide which things you need
  3. If you want to use native file-uploader (nginx_upload_module written in C) instead of python uploader (which is a lot slower) you should build nginx yourself. For archlinux setup requires pacman -S python-lxml gd make geoip. To build nginx with this module run from the root user: bash download_content.sh build_nginx 1.15.3 2.3.0. And create dir + user useradd nginx; install -d -m 0500 -o http -g http /var/cache/nginx/. If you don't, just install nginx with your package manager: e.g. pacman -S nginx or yum install nginx on centos
  4. Follow Bootstrap files flow.
  5. I preconfigued native setup for domain pychat.org, you want to replace all occurrences of pychat.org in rootfs directory for your domain. To simplify replacing use my script: ./download_content.sh rename_domain your.new.domain.com. Also check rootfs/etc/nginx/sites-enabled/pychat.conf if server_name section is correct after renaming.
  6. HTTPS is required for webrtc calls so you need to enable ssl:
  • Either create your certificates e.g. openssl req -nodes -new -x509 -keyout server.key -out certificate.crt -days 3650
  • Either use something like certbot
  • Either you already have certificates or already know how to do it.
  1. Open /etc/nginx/sites-enabled/pychat.conf and modify it by:
  • change server_name to one matching your domain/ip address
  • remove check for host below it, if you're using ip
  • change ssl_certificate and ssl_certificate_key path to ones that you generated
  • if you didn't compile nginx with upload_file module, remove locations api/upload_file and @upload_file, otherwise leave it as it is.
  1. Change to parent directory (which contains frontend and backend) and Copy config files to rootfs with from root user sh download_content.sh copy_root_fs.
  2. Create a directory mkdir backend/downloading_photos in the backend directory and give it access chmod 777 downloading_photos cDon't forget to change the owner of current (project) directory to http user: chown -R http:http. And reload systemd config systemctl daemon-reload. Also you
  3. Follow the Frontend steps
  4. Generate postfix files: install -d -m 0555 -o postfix -g postfix /etc/postfix/virtual; postmap /etc/postfix/virtual; newaliases; touch /etc/postfix/virtual-regexp; echo 'root postmaster' > /etc/aliases
  5. Start services:
  • For archlinux/ubuntu: packages=( mysqld redis [email protected] nginx postfix ) ; for package in "${packages[@]}" ; do systemctl enable $package; done;. Service mysqld could be named mysql on Ubuntu.
  • For centos: packages=( redis-server nginx postfix mysqld [email protected]) ; for package in "${packages[@]}" ; do service $package start; done;
  1. You can also enable autostart (after reboot)
  • For archlinux/ubuntu: packages=( redis nginx postfix mysqld tornado) ; for package in "${packages[@]}" ; do systemctl start $package; done;
  • For centos: chkconfig mysqld on; chkconfig on; chkconfig tornado on; chkconfig redis on; chkconfig postfix on
  1. Open in browser https://your.domain.com. Note that by default nginx accepts request by domain.name rather than ip.
  2. If something doesn't work you want to check logs:
  • Check logs in pychat/backend/logs directory.
  • Check daemon logs: e.g. on Archlinux sudo journalctl -u YOUR_SERVICE. Where YOUR_SERVICE could be: nginx, mysql, tornado
  • Check that user http has access to you project directory, and all directories inside, especially to /photos

Frontend

  • cd frontend; nvm install; nvm use.
  • yarn install --frozen-lockfile
  • Create production.json based on Frontend config. Also you can use and modify cp docker/pychat.org/production.json ./frontend/
  • Run yarn run prod. This generates static files in frotnend/dist directory.

Desktop app

Pychat uses websql and built the way so it renders everything possible w/o network. You have 3 options:

PWA

This is the simplest one. Just open settings page from you user and click "Add to home screen". Note that PWA is only available from chrome and chrome android. No support for IOS and other browsers. But PWA is the most stable from ones below.

Natifier

Use nativifier to create a client (replace pychat.org for your server): npx run nativifier pychat.org

Electron

  • Create production.json based on Frontend config
  • Run cd frontend; yarn run electronProd.

Android app

You can use PWA as it's described in desktop app section which I recommend. Other way is cordova which is a lot harder. If you're not familiar with android SDK I would recommend doing the steps below from AndroidStudio:

  • Install android sdk, android platform tools. accept license
  • Create production.json based on Frontend config
  • production.json "PUBLIC_PATH": "./", "BACKEND_ADDRESS": "pychat.org" build into dist, rm .gz. , copy to www. In index.html include <script src="cordova.js"></script>
  • bash download_content.sh android

Example for mac:

  1. Download oracle jdk-8
  2. Install android studio
  3. Run android studio that will install Android sdk for you
  4. Accept licence with ~/Library/Android/sdk/tools/bin/sdkmanager --licenses
  5. Install gradle. brew install gradle
  6. Open frontend/platforms/android with androidStudio
  7. Start android emulator / connect device
  8. put index.html into www
  9. Run dev server with yarn run dev; bash download_content.sh android
  10. TO debug java files you can run it directory from android studio. Debug button should be available out of the box after openning a project
  11. To debug js you can open chrome://inspect/#devices in chrome
  12. For any question check cordova docs

Development setup

The flow is the following

  • Install OS packages depending on your OS type
  • Bootstrap files
  • Build frontend
  • Start services and check if it works

Install OS packages

This section depends on the OS you use. I tested full install on Windows/Ubuntu/CentOs/MacOS/Archlinux/Archlinux(rpi3 armv7). pychat.org currently runs on Archlinux Raspberry Pi 3.

Windows:

  1. Install python with pip. only Python 3.6+ is required
  2. Add pip and python to PATH variable.
  3. Install redis. Get the newest version or at least 2.8.
  4. Install mysql. You basically need mysql server and python connector.
  5. You also need to install python's mysqlclient. If you want to compile one yourself you need to vs2015 tools. You can download visual-studio and install Common Tools for Visual C++ 2015. You need to run setup as administrator. The only connector can be found here. The wheel (already compiled) connectors can be also found here Mysqlclient. Use pip to install them.
  6. Add bash commands to PATH variable. Cygwin or git's will do find.(for example if you use only git PATH=C:\Program Files\Git\usr\bin;C:\Program Files\Git\bin).
  7. Install nvm.

Ubuntu:

  1. Install required packages: apt-get install python pip mysql-server libmysqlclient-dev (python should be 3.6-3.8) If pip is missing check python-pip. For old versions of Ubuntu you can use this ppa: sudo add-apt-repository ppa:deadsnakes/ppa; sudo apt-get update; sudo apt-get install python3.8 python3.8-dev python3.8-venv python3.8-apt; curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py; python3.8 get-pip.py
  2. Install redis database: add-apt-repository -y ppa:rwky/redis; apt-get install -y redis-server
  3. Install mysqlclient pip install mysqlclient==1.3.13
  4. Install nvm

Archlinux:

  1. Install system packages: pacman -S unzip python python-pip redis yarn mariadb python-mysqlclient. nvm is located in aur so yay -S nvm (or use another aur package)
  2. If you just installed mariadb you need to initialize it: mysql_install_db --user=mysql --basedir=/usr --datadir=/var/lib/mysql.

MacOS

  1. Install packages: brew install mysql redis python3
  2. Start services brew services run mysql redis
  3. Install mysqlclient pip install mysqlclient

Ssl

Since we're using self singed certificate your OS doesn't know about for development. We need to do some tricks for browser to make it work. If you have valid certificates for your domain you can skip this step.

  1. I used the following commands to generate a new self signed certificate. You can use mine located in frontend/certs directory. So you can skip this text
cd frontend/certs
openssl genrsa -out private.key.pem 4096
openssl req -new -sha256 -out root.ca.pem -key private.key.pem -subj '/CN=localhost' -extensions EXT -config <( printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")
openssl x509 -req -days 3650 -in root.ca.pem -signkey private.key.pem -out server.crt.pem -extfile ./v3.ext

Useful links:

  1. You have multiple options:
  • Install development certificate on operating system. Each os will require own configuration. E.g. macos do
    • browser-1
    • Drag and drop for image near localhost to finderbrowser-1
    • Double click on newly created file and go to All items, select localhost and mark it as 'Always trust' macos-cert
  • Click on Proceed unsafe when accessing your site. Proceed unsafe may be unavailable in some cases. E.g. for MacOS chrome you can use hack: just type thisisunsafe while you see certificate error
  • If you use different ports for back and front (like its described above) you may need to accept certificate from localhost:8888 (use for api) as well. For that open https://localhost:8888
  • Tell Browser to ignore certificate:
  • E.g. for chrome you can enable invalid certificates for localhost in chrome://flags/#allow-insecure-localhost.
  • If flag is not available you can also launch chrome with custom flag: --ignore-certificate-errors flag. E.g. on MacOS open -a Google\ Chrome --args --ignore-certificate-errors Remember that Service Worker will work only if certificate is trusted. So flags like ignore-ceritifcate-errors won't work. But installing certifcate to root system will.

Bootstrap files:

  1. I use 2 git repos in 2 project directory. So you probably need to rename excludeMAINfile to .gitignoreor create link to exclude. ln -rsf .excludeMAIN .git/info/exclude
  2. Rename backend/chat/settings_example.py to backend/chat/settings.py. Modify file according to the comments in it.
  3. From backend dir (cd backend). Create virtualEnv python3 -m venv --system-site-packages .venv. For ubuntu you can omit --system-site-packages. Activate it: source .venv/bin/activate
  4. Install python packages with pip install -r requirements.txt. (Remember you're still in backend dir)
  5. From root (sudo) user create the database (from shell environment): echo "create database pychat CHARACTER SET utf8 COLLATE utf8_general_ci; CREATE USER 'pychat'@'localhost' identified by 'pypass'; GRANT ALL ON pychat.* TO 'pychat'@'localhost';" | mysql -u root. You will need mysql running for that (e.g. systemctl start mysql on archlinux) If you also need remote access do the same with '192.168.1.0/255.255.255.0';
  6. Fill database with tables: bash ../download_content.sh create_django_tables. (Remember you're still in backend dir)

Build frontend

Change to frontend directory cd frontend I would recommend to use node version specified in nvm, so nvm install; nvm use.

  • To get started install dependencies first: yarn install --frozen-lock # or use npm if you're old and cranky

  • Take a look at copy development.json. The description is at Frontend config

  • Webpack-dev-server is used for development purposes with hot reloading, every time you save the file it will automatically apply. This doesn't affect node running files, only watching files. So files like builder.js or development.json aren't affected. To run dev-server use yarn run devProxy. Backend should be running during that. Otherwise use yarn run dev. You can navigate to http://localhost:8080.

  • To build android use yarn run android -- 192.168.1.55 where 55 is your bridge ip address

  • To run electron use yarn run electronDev. This will start electron dev. and generate /tmp/electron.html and /tmp/electron.js

Configure IDEs if you use it:

Pycharm

  1. I recommend open backend as root directory for pycharm.
  2. Django support should be enabled by default when you open this project. If it doesn't happen go to Settings -> Languages and Framework -> Django -> Enable django support.
  • Django project root: backend
  • Put Settings: to chat/settings.py
  1. If pycharm didn't configure virtualenv itself. Go to Settings -> Project backend -> Project Interpreter -> Cogs in right top -> 'Add' -> Virtual Environment -> Existing environment -> Interpereter = pychatdir/.venv/bin/python. Click ok. In previous menu on top 'Project interpreter` select the interpriter you just added.
  2. Settings -> Project backend -> Project structure
  • You might want to exclude: .idea
  • mark templates directory as Template Folder
  1. Add tornado script: Run -> Edit configuration -> Django server -> Checkbox Custom run command start_tornado. Remove port value.

Linting

Current linting supports:

Webstorm

Set template

  1. New
  2. Edit files templates...
  3. Vue single file component
<template>
    <div>#[[$END$]]#</div>
</template>

<script lang="ts">
  import {State} from '@/utils/store';
  import {Component, Prop, Vue, Watch, Ref} from 'vue-property-decorator';

  @Component
  export default class ${COMPONENT_NAME} extends Vue {
   
  }
</script>
<style lang="sass" scoped>

</style>

Change linting settings

Disable tslint, since it's not used, and enable eslint:

  1. Settings
  2. Typescript
  3. Tslint
  4. Disable tslint

Enable aliases for webpack

  • to resolve absolute path for webpack webstorm requires webpack.config.js. Go to settings -> javascript -> webpack -> Webpack config file

Start services and run:

  • Start mysql server if it's not started.
  • Start session holder: redis-server
  • Start webSocket listener: python manage.py start_tornado
  • Open in browser https://127.0.0.1:8080.
  • Check ssl section TODO

Contribution guide

Description

Pychat is written in Python and typescript. For handling realtime messages WebSockets are used: browser support on client part and asynchronous framework Tornado on server part. For ORM django was used with MySql backend. Messages are being broadcast by means of redis pub/sub feature using tornado-redis backend. Redis is also used as django session backend and for storing current users online. For video call WebRTC technology was used with stun server to make a connection, which means you will always get the lowest ping and the best possible connection channel. Client part is written with progressive js framework VueJs which means that pychat is SPA, so even if user navigates across different pages websocket connection doesn't break. Pychat also supports OAuth2 login standard via FaceBook/Google. Css is compiled from sass. Server side can be run on any platform Windows, Linux, Mac. Client (users) can use Pychat from any browser with websocket support: IE11, Edge, Chrome, Firefox, Android, Opera, Safari...

Shell helper

Execute bash download_content.sh it will show you help.

Frontend logging

By default each user has turned off browser (console) logs. You can turn them on in /#/profile page (logs checkbox). All logs are logged with window.logger object, for ex: window.logger('message')(). Note that logger returns a function which is binded to params, that kind of binding shows corrent lines in browser, especially it's handy when all source comes w/o libraries/webpack or other things that transpiles or overhead it. You can also inspect ws messages here for chromium. You can play with window.wsHandler.handleMessage(object) and window.wsHandler.handle(string) methods in debug with messages from log to see what's going on

Icons

Chat uses fontello and its api for icons. The decision is based on requirements for different icons that come from different fonts and ability to add custom assets. Thus the fonts should be generated (.wolf etc). W/o this chat would need to download a lot of different fonts which would slow down the loading process. You can easily edit fonts via your browser, just execute bash download_content.sh post_fontello_conf. Make your changes and hit "Save session". Then execute bash download_content.sh download_fontello. If you did everything right new icons should appear under frontend/src/assets/demo.html

Sustaining online protocol

Server pings clients every PING_INTERVAL miliseconds. If client doesn't respond with pong in PING_CLOSE_JS_DELAY, server closes the connection. If ther're multiple tornado processes if can specify port for main process with MAIN_TORNADO_PROCESS_PORT. In turn the client expects to be pinged by the server, if client doesn't receive ping event it will close the connection as well. As well page has window listens for focus and sends ping event when it receives it, this is handy for situation when pc suspends from ram.

Database migrations

Pychat uses standard django migrations tools. So if you updated your branch from my repository and database has changed you need to ./manage.py makemigration and ./manage.py migrate. If automatic migration didn't work I also store migrations in migration. So you might take a look if required migration is there before executing commands. If you found required migration in my repo don't forget to change Migration.dependencies[] and rename the file.

Screen sharing for Chrome v71 or less

ScreenShare available for Chrome starting from v71. For chrome v31+ you should install an extension. It uses chrome.desktopCapture feature that is available only via extension. The extension folder is located under screen_cast_extension`. If you want to locally test it:

  • Open chrome://extensions/ url in chrome and verify that developer mode checkbox is checked.
  • In the same tab click on load unpacked extension... button and select screen_cast_extension directory.
  • Note that in order to background.js be able to receive messages from webpage you need to add your host to externally_connectable section in manifest.json

Tp publish extension:

  • If you want to update existing extension don't forget to increment version in manifest.json.
  • Zip screen_cast_extension directory into e.g. bash download_content.sh zip_extension
  • Upload archive extension.zip to chrome webstore (Note, you need to have a developer account, that's 5$ worth atm).

WebRTC connection establishment

The successful connection produces logs below in console

Sender:

ws:in {"action": "offerCall", "content": {"browser": "Chrome 86"}, "userId": 2, "handler": "webrtc", "connId": "YZnbgKIL", "opponentWsId": "0002:UFBW", "roomId": 1, "time": 1604446797449}
WRTC Setting call status to  received_offer    
WRTC CallHandler initialized
ws:out  {"action":"replyCall","connId":"YZnbgKIL","content":{"browser":"Chrome 86"},"messageId":1} 
rsok33GN CallHandler initialized
rsok33GN:0005:EJAd Created CallSenderPeerConnection
WRTC Setting call status to  accepted
WRTC capturing input
WRTC navigator.mediaDevices.getUserMedia({audio, video})
ws:out  {"action":"acceptCall","connId":"YZnbgKIL","messageId":2}
YZnbgKIL:0002:UFBW Connect to remote  
rsok33GN:0005:EJAd Creating RTCPeerConnection
YZnbgKIL:0002:UFBW Sending local stream to remote
rsok33GN:0005:EJAd Creating offer...
rsok33GN:0005:EJAd Created offer, setting local description
rsok33GN:0005:EJAd Sending offer to remote
YZnbgKIL:0002:UFBW onicecandidate
...
YZnbgKIL:0002:UFBW onicecandidate
rsok33GN:0005:EJAd onsendRtcData
rsok33GN:0005:EJAd answer received
rsok33GN:0005:EJAd onaddstream
rsok33GN:0005:EJAd onsendRtcData

Receiver:

WRTC capturing input
WRTC navigator.mediaDevices.getUserMedia({audio, video})
WRTC got local stream  MediaStream {id: "0IeyYT9LxHRidUZaw7XSVnXEPWYimm4KDmJB", active: true, onaddtrack: null, onremovetrack: null, onactive: null, …}
WRTC Setting call status to  sent_offer
ws:out  {"action":"offerCall","roomId":1,"content":{"browser":"Chrome 86"},"messageId":1}
ws:in {"action": "setConnectionId", "handler": "void", "connId": "YZnbgKIL", "messageId": 1, "time": 1604446797449}   
rsok33GN CallHandler initialized
rsok33GN:0004:oIc5 Created CallReceiverPeerConnection
YZnbgKIL:0001:qobF Connect to remote
rsok33GN:0004:oIc5 Creating RTCPeerConnection
YZnbgKIL:0001:qobF Sending local stream to remote
rsok33GN:0004:oIc5 onsendRtcData
rsok33GN:0004:oIc5 Creating answer
rsok33GN:0004:oIc5 onaddstream
rsok33GN:0004:oIc5 Sending answer
rsok33GN:0004:oIc5 onsendRtcData
rsok33GN:0004:oIc5 onsendRtcData

The string rsok33GN:0005:EJAd describes:

  • rsok33GN is ID of CallHandler
  • 0005 is Id of user
  • EJAd id of connection (TornadoHandler.id)

TO see current connections and their info check chrome://webrtc-internals/ Read this article to understand how JSEP architecture works. SEE WEBRTC_CONFIG at development.json. I personally use turn server coturn, It needs ports 3478 to be exposed.

Frontend Stack

The technologies stack used in project:

  • Typescript
  • Vue, Vuex, VueRouter, lines-logger
  • Vuex-module-decorators, Vue-property-decorator
  • Webpack and loaders
  • Sass

builder.js is used to build project. Take a look at it to understand how source files are being processed. Its start point is entry: ['./src/main.ts']. Everything is imported in this files are being processed by section loaders.

Every vue component has injected .$logger object, to log something to console use this.logger.log('Hello {}', {1:'world'})(); Note calling function again in the end. Logger is disabled for production. For more info visit lines-logger

This project uses vue-property-decorator (that's has a dependency vue-class-component) vuex-module-decorators. You should write your component as the following:

import { Vue, Component, Prop, Watch, Emit, Ref } from 'vue-property-decorator'
import {userModule, State} from '@/utils/storeHolder'; // vuex module example


@Component
export class MyComp extends Vue {
  
  @Ref
  button: HTMLInputElement;

  @Prop readonly propA!: number;
  
  @State
  public readonly users!: User[];

  @Watch('child')
  onChildChanged(val: string, oldVal: string) { }

  @Emit() 
  changedProps() {}

  async created() {
    userModule.setUsers(await this.$api.getUsers());
  }
}

Frontend config

development.json and production.json have the following format:

{
  "BACKEND_ADDRESS": "e.g. pychat.org:443, protocol shouldn't be there, note there's no trailing slash, you can specify '{}' to use the same host as files served with",
  "IS_DEBUG": "set true for development and debug mode enabled",
  "UGLIFY": "true/false uglifies js/css so it has less weight, set this for production.json only, when you're sue you don't need to debug the output",
  "GOOGLE_OAUTH_2_CLIENT_ID" : "check chat/settings_example.py",
  "FACEBOOK_APP_ID": "check chat/settings_example.py",
  "MANIFEST": "manifest path for firebase push notifications e.g.`/manifest.json`",
  "RECAPTCHA_PUBLIC_KEY": "check chat/settings_example.py RECAPTCHA_SITE_KEY",
  "AUTO_REGISTRATION": "if set to true, for non loggined user registration page will be skipped with loggining with random generated username. Don't use RECAPTCHA with this key",
  "PUBLIC_PATH": "Set this path if you have different domains/IPs for index.html and other static assets, e.g. I serve index.html directly from my server and all sttatic assets like main.js from CDN, so in my case it's 'https://static.pychat.org/' note ending slash",
  "ISSUES": "if true navigation bar will display link to reporting a issue page",
  "STATISTICS": "if true navigation bar will display a link to a page with statistics user by country",
  "GITHUB_LINK": "an external link to project source files, in my case https://github.com/Deathangel908/pychat . Set to false if you don't wanna see it in the navbar",
  "FLAGS": "if true, a user name will contain a country icon on the right. User names are shown on the right section of the screen",
  "WEBRTC_CONFIG": "This variable defines the first argument of RtcPeerConnection constructor. Sometimes webrtc stun server doesn't work in establishing a connection. Especially for this you can use turn server instead of it. Docker prod docker image already comes with a turn server, example of configuration for it  `{iceServers:[{urls:['turn:YOUR_DOMAIN'],username:'pychat',credential:'pypass'}]}`. replace YOUR_DOMAIN with your real domain name/public ip. You other scenarios use your server like coturn (https://github.com/coturn/coturn). See more info of this variable at docs: https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/RTCPeerConnection#RTCConfiguration_dictionary"
}

Github actions

In order to setup continuous delivery via github:

  • Generate a new pair of ssh keys mkdir /tmp/sshkey; ssh-keygen -t rsa -b 4096 -C "github actions" -f /tmp/sshkey/id_rsa
  • put /tmp/sshkey/id_rsa.pub to server ~/.ssh/authorized_keys where ~ is the home for ssh user to use ( I used http)
  • Create ssh variables at https://github.com/akoidan/pychat/settings/secrets/actions (where akoidan/pychat is your repo) :
    • HOST -ssh host (your domain)
    • PORT - ssh port (22)
    • SSH_USER - ssh user, if you used my setup it's http
    • ID_RSA - what ssh-keygen has generated in step above to/tmp/sshkey/id_rsa
  • I used alias to give http user to access tornado systemd service like in this example. So append /etc/sudoers with
Cmnd_Alias RESTART_TORNADO = /usr/bin/systemctl restart tornado
http ALL=(ALL) NOPASSWD: RESTART_TORNADO

TODO

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].