v0.0.0-...-9d99875 Latest Latest

This package is not in the latest version of its module.

Go to latest
Published: Oct 24, 2021 License: GPL-2.0 Imports: 20 Imported by: 0



Laplace is an open-source project to enable screen sharing directly via browser. Made possible using WebRTC for low latency peer-to-peer connections, and WebSocket implemented in golang for WebRTC signaling.

Demo video:

Laplace for gaming

Try Demo

For demo, you can visit

Website screenshot


There are already possible solutions to share your computer screen, e.g. TeamViewer. But most of them require installations of software or plugins. What Laplace provides is a simple solution to this problem. For users wanting to share their screen, all they need to do is to open a website page with their browsers, clicking some buttons, then share some session ID with their peers. No installation or registration required.

Solving the latency problem

This project also serves as a proof-of-concept (PoC) for screen sharing capability directly in browsers based on WebRTC. Using WebRTC, real-time communication is made possible through peer-to-peer connections. This proves to be very useful in solving one of the biggest problems is screen streaming: Latency. The latency represents how long the delay is from the source to transmit to the remote client. If you notice, this latency problem is usually highlighted by game streaming services, since gameplay relies heavily on the interactivity of inputs and outputs.

Low server cost

This solution also solves the server cost problem, since the expensive operations (encoding and transmission) are done on client browsers. The server is only needed for serving frontends and for WebRTC signaling.

Possible Use Cases
  • Game streaming from PC to mobile devices.
  • Collaborative work where you need to share your screen with remote coworkers.
  • Mirroring presentation slides and demonstrations.


Build from source

$ git clone
$ cd laplace && go build -o laplace main.go
$ ./laplace --help

OR, pull the pre-built docker image

$ docker pull adamyordan/laplace
$ docker run adamyordan/laplace ./laplace --help

Program Execution

Executing this project basically serves an HTTP server that will host the frontend and the WebSocket implementation. Note that you sometimes need to run HTTPs in order for browser to connect to websocket.

$ ./laplace --help
  -addr string
        Listen address (default "")
  -certFile string
        TLS cert file (default "files/server.crt")
  -keyFile string
        TLS key file (default "files/server.key")
        Use TLS (default true)

By default, you can run the executable without any argument to listen to TLS port 443. A self-signed certificate files are provided to ease up development.

$ ./laplace
2020/03/25 01:01:10 Listening on TLS:

You can then open https://localhost:443/ to view Laplace page. You may need to add certificate exceptions. In Chrome, you can type thisisunsafe.


Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.






This section is empty.


This section is empty.


func CheckRunPlugin

func CheckRunPlugin(PluginName string, ID string) error

CheckRunPlugin Checks if the ID belongs to the group or container calls the plugin function the appropriate amount of times

func DeletePlugin

func DeletePlugin(pluginname string) error

DeletePlugin The following function deletes a plugin based on the plugin name provided.

func DownloadPlugin

func DownloadPlugin(pluginurl string) error

DownloadPlugin This functions downloads package from a git repo.

func RunPluginContainer

func RunPluginContainer(PluginName string, ContainerID string) error

RunPluginContainer Runs ansible plugin based on plugin name and container name which is derived from the tracked containers file We pass in the group ID as a parameter because when we modify the ports taken


type ExecuteIP

type ExecuteIP struct {
	ContainerID string
	IPAddress   string
	SSHPortNo   string
	Success     bool

ExecuteIP IP Address to execute Ansible instruction

func (*ExecuteIP) ModifyHost

func (e *ExecuteIP) ModifyHost(p *Plugin) error

ModifyHost adds IP address , port no to the config file

func (*ExecuteIP) RunAnsible

func (e *ExecuteIP) RunAnsible(p *Plugin) error

RunAnsible Executes based on credentials on the struct

type Host

type Host struct {
	All struct {
		Vars struct {
			AnsiblePythonInterpreter string `yaml:"ansible_python_interpreter"`
		} `yaml:"vars"`
	} `yaml:"all"`
	Main struct {
		Hosts struct {
			Host1 struct {
				AnsibleHost     string `yaml:"ansible_host"`
				AnsiblePort     int    `yaml:"ansible_port"`
				AnsibleUser     string `yaml:"ansible_user"`
				AnsibleSSHPass  string `yaml:"ansible_ssh_pass"`
				AnsibleSudoPass string `yaml:"ansible_sudo_pass"`
			} `yaml:"host1"`
		} `yaml:"hosts"`
	} `yaml:"main"`

Host Struct for ansible host Generated from

func ReadHost

func ReadHost(filename string) (*Host, error)

ReadHost Reads host file and adds

type Plugin

type Plugin struct {
	FolderName        string
	PluginDescription string

	Execute    []*ExecuteIP
	NumOfPorts int
	// contains filtered or unexported fields

Plugin Information about the plugins available

func RunPlugin

func RunPlugin(pluginName string, IPAddresses []*ExecuteIP) (*Plugin, error)

RunPlugin Executes plugins based on the plugin name provided

func SearchPlugin

func SearchPlugin(pluginname string) (*Plugin, error)

SearchPlugin Detects plugin information based on the name provided on the parameter

func (*Plugin) AutoSetPorts

func (p *Plugin) AutoSetPorts(containerID string) error

AutoSetPorts Automatically maps free ports to site.yml file

func (*Plugin) CopyToTmpPlugin

func (p *Plugin) CopyToTmpPlugin() error

CopyToTmpPlugin This function would ensure that we create a copy of the plugin in the tmp directory, and it would be executed from there. This due to the reason of automating port allocation when running plugins

func (*Plugin) ExecutePlugin

func (p *Plugin) ExecutePlugin() error

ExecutePlugin Function to execute plugins that are called

func (*Plugin) NumPorts

func (p *Plugin) NumPorts() error

NumPorts Gets the Number the ports the plugin requires

type Plugins

type Plugins struct {
	PluginsDetected []*Plugin

Plugins Array of all plugins detected

func DetectPlugins

func DetectPlugins() (*Plugins, error)

DetectPlugins Detects all the plugins available

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL