• Stars
    star
    1,193
  • Rank 39,220 (Top 0.8 %)
  • Language
    Go
  • License
    MIT License
  • Created almost 10 years ago
  • Updated almost 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Async peer communication protocol & library

gotalk

Gotalk exists to make it easy for programs to talk with one another over the internet, like a web app coordinating with a web server, or a bunch of programs dividing work amongst each other.

GitHub tag (latest SemVer) PkgGoDev Go Report Card

Gotalk...

  • is an efficient, easily debuggable multiplexing data transfer protocol
  • is transport agnostic: works on any byte stream
  • offers a high-level, easy-to-get-started API for WebSockets
  • enables arbitrary number of requests & responses over a single persistent connection
  • includes a small built-in JavaScript library
  • provides a small and focused Go API

Go API Documentation on godoc.org โ†’

Usage

Gotalk is a simple go module - import it into your program and go build:

import "github.com/rsms/gotalk"

To use a specific version, run go get github.com/rsms/[email protected] (substituting the version number for the version you desire.)

Examples can be found in the examples directory. Build them with go build:

$ cd examples/websocket-chat
$ go build
$ ./websocket-chat
Listening on http://localhost:1235/

Here's a minimal but complete example program: (examples/websocket-minimal)

package main
import (
  "net/http"
  "github.com/rsms/gotalk"
)
func main() {
  gotalk.Handle("echo", func(in string) (string, error) {
    return in, nil
  })
  http.Handle("/gotalk/", gotalk.WebSocketHandler())
  http.Handle("/", http.FileServer(http.Dir(".")))
  print("Listening on http://localhost:1234/\n")
  panic(http.ListenAndServe("localhost:1234", nil))
}

Developing Gotalk & contributing

See CONTRIBUTING.md

Other implementations

Introduction

A terribly boring amateur comic strip

Gotalk takes the natural approach of bidirectional and concurrent communication โ€” any peer have the ability to expose "operations" as well as asking other peers to perform operations. The traditional restrictions of who can request and who can respond usually associated with a client-server model is nowhere to be found in Gotalk.

Gotalk in a nutshell

Bidirectional โ€” There's no discrimination on capabilities depending on who connected or who accepted. Both "servers" and "clients" can expose operations as well as send requests to the other side.

Concurrent โ€” Requests, results, and notifications all share a single connection without blocking each other by means of pipelining. There's no serialization on request-result or even for a single large message, as the Gotalk protocol is frame-based and multiplexes messages over a single connection. This means you can perform several requests at once without having to think about queueing or blocking.

Diagram of how Gotalk uses connection pipelining

Simple โ€” Gotalk has a simple and opinionated API with very few components. You expose an operation via "handle" and send requests via "request".

Debuggable โ€” The Gotalk protocol's wire format is ASCII-based for easy on-the-wire inspection of data. For example, here's a protocol message representing an operation request: r0001005hello00000005world. The Gotalk protocol can thus be operated over any reliable byte transport.

Practical โ€” Gotalk includes a JavaScript implementation for Web Sockets alongside the full-featured Go implementation, making it easy to build real-time web applications. The Gotalk source code also includes a number of easily-readable examples.

By example

There are a few examples in the examples directory demonstrating Gotalk. But let's explore a simple program right now โ€” here's a little something written in Go which demonstrates the use of an operation named "greet":

func server() {
  gotalk.Handle("greet", func(in GreetIn) (GreetOut, error) {
    return GreetOut{"Hello " + in.Name}, nil
  })
  if err := gotalk.Serve("tcp", "localhost:1234"); err != nil {
    log.Fatalln(err)
  }
}

func client() {
  s, err := gotalk.Connect("tcp", "localhost:1234")
  if err != nil {
    log.Fatalln(err)
  }
  greeting := &GreetOut{}
  if err := s.Request("greet", GreetIn{"Rasmus"}, greeting); err != nil {
    log.Fatalln(err)
  }
  log.Printf("greeting: %+v\n", greeting)
  s.Close()
}

Let's look at the above example in more detail, broken apart to see what's going on.

We begin by importing the gotalk library together with log which we use for printing to the console:

package main
import (
  "log"
  "github.com/rsms/gotalk"
)

We define two types: Expected input (request parameters) and output (result) for our "greet" operation:

type GreetIn struct {
  Name string `json:"name"`
}
type GreetOut struct {
  Greeting string `json:"greeting"`
}

Registers a process-global request handler for an operation called "greet" accepting parameters of type GreetIn, returning results of type GreetOut:

func server() {
  gotalk.Handle("greet", func(in GreetIn) (GreetOut, error) {
    return GreetOut{"Hello " + in.Name}, nil
  })

Finally at the bottom of our server function we call gotalk.Serve, which starts a local TCP server on port 1234:

  if err := gotalk.Serve("tcp", "localhost:1234"); err != nil {
    log.Fatalln(err)
  }
}

In out client function we start by connecting to the server:

func client() {
  s, err := gotalk.Connect("tcp", "localhost:1234")
  if err != nil {
    log.Fatalln(err)
  }

Finally we send a request for "greet" and print the result:

  greeting := GreetOut{}
  if err := s.Request("greet", GreetIn{"Rasmus"}, &greeting); err != nil {
    log.Fatalln(err)
  }
  log.Printf("greeting: %+v\n", greeting)

  s.Close()
}

Output:

greeting: {Greeting:Hello Rasmus}

Gotalk in the web browser

Gotalk is implemented not only in the full-fledged Go package, but also in a JavaScript library. This allows writing web apps talking Gotalk via Web Sockets possible.

// server.go:
package main
import (
  "net/http"
  "github.com/rsms/gotalk"
)
func main() {
  gotalk.Handle("echo", func(in string) (string, error) {
    return in, nil
  })
  http.Handle("/gotalk/", gotalk.WebSocketHandler())
  http.Handle("/", http.FileServer(http.Dir(".")))
  err := http.ListenAndServe("localhost:1234", nil)
  if err != nil {
    panic(err)
  }
}

In our html document, we begin by registering any operations we can handle:

<!-- index.html -->
<body>
<script type="text/javascript" src="/gotalk/gotalk.js"></script>
<script>
gotalk.handle('greet', function (params, result) {
  result({ greeting: 'Hello ' + params.name });
});
</script>

Notice how we load a JavaScript from "/gotalk/gotalk.js" โ€” a gotalk web socket server embeds a matching web browser JS library which it returns from {path where gotalk web socket is mounted}/gotalk.js. It uses Etag cache validation, so you shouldn't need to think about "cache busting" the URL.

We can't "listen & accept" connections in a web browser, but we can "connect" so we do just that:

<!-- index.html -->
<body>
<script type="text/javascript" src="/gotalk/gotalk.js"></script>
<script>
gotalk.handle('greet', function (params, result) {
  result({ greeting: 'Hello ' + params.name });
});

var s = gotalk.connection().on('open', function () {
  // do something useful
}).on('close', function (err) {
  if (err.isGotalkProtocolError) return console.error(err);
});
</script>

This is enough for enabling the server to do things in the browser ...

But you probably want to have the browser send requests to the server, so let's send a "echo" request just as our connection opens:

var s = gotalk.connection().on('open', function () {
  s.request("echo", "Hello world", function (err, result) {
    if (err) return console.error('echo failed:', err);
    console.log('echo result:', result);
  });
});

We could rewrite our code like this to allow some UI component to send a request:

var s = gotalk.connection();

button.addEventListener('click', function () {
  s.request("echo", "Hello world", function (err, result) {
    if (err) return console.error('echo failed:', err);
    console.log('echo result:', result);
  });
});

The request will fail with an error "socket is closed" if the user clicks our button while the connection isn't open.

There are two ways to open a connection on a socket: Sock.prototype.open which simply opens a connection, and Sock.prototype.openKeepAlive which keeps the connection open, reconnecting as needed with exponential back-off and internet reachability knowledge. gotalk.connection() is a short-hand for creating a new Sock with gotalk.defaultHandlers and then calling openKeepAlive on it.

Protocol and wire format

The wire format is designed to be human-readable and flexible; it's byte-based and can be efficiently implemented in a number of environments ranging from HTTP and WebSocket in a web browser to raw TCP in Go or C. The protocol provides only a small set of operations on which more elaborate operations can be modeled by the user.

This document describes protocol version 1

Here's a complete description of the protocol:

conversation    = ProtocolVersion Message*
message         = SingleRequest | StreamRequest
                | SingleResult | StreamResult
                | ErrorResult | RetryResult
                | Notification | ProtocolError

ProtocolVersion = <hexdigit> <hexdigit>

SingleRequest   = "r" requestID operation payload
StreamRequest   = "s" requestID operation payload StreamReqPart*
StreamReqPart   = "p" requestID payload
SingleResult    = "R" requestID payload
StreamResult    = "S" requestID payload StreamResult*
ErrorResult     = "E" requestID payload
RetryResult     = "e" requestID wait payload
Notification    = "n" name payload
Heartbeat       = "h" load time
ProtocolError   = "f" code

requestID       = <byte> <byte> <byte> <byte>

operation       = text3
name            = text3
wait            = hexUInt8
code            = hexUInt8
time            = hexUInt8
load            = hexUInt4

text3           = text3Size text3Value
text3Size       = hexUInt3
text3Value      = <<byte>{text3Size} as utf8 text>

payload         = payloadSize payloadData
payloadSize     = hexUInt8
payloadData     = <byte>{payloadSize}

hexUInt3        = <hexdigit> <hexdigit> <hexdigit>
hexUInt4        = <hexdigit> <hexdigit> <hexdigit> <hexdigit>
hexUInt8        = <hexdigit> <hexdigit> <hexdigit> <hexdigit>
                  <hexdigit> <hexdigit> <hexdigit> <hexdigit>

Handshake

A conversation begins with the protocol version:

01  -- ProtocolVersion 1

If the version of the protocol spoken by the other end is not supported by the reader, a ProtocolError message is sent with code 1 and the connection is terminated. Otherwise, any messages are read and/or written.

Single-payload requests and results

This is a "single-payload" request ...

+------------------ SingleRequest
|   +---------------- requestID   "0001"
|   |      +--------- operation   "echo" (text3Size 4, text3Value "echo")
|   |      |       +- payloadSize 25
|   |      |       |
r0001004echo00000019{"message":"Hello World"}

... and a corresponding "single-payload" result:

+------------------ SingleResult
|   +---------------- requestID   "0001"
|   |       +-------- payloadSize 25
|   |       |
R000100000019{"message":"Hello World"}

Each request is identified by exactly three bytesโ€”the requestIDโ€”which is requestor-specific and has no purpose beyond identity, meaning the value is never interpreted. 4 bytes can express 4 294 967 296 different values, meaning we can send up to 4 294 967 295 requests while another request is still being served. Should be enough.

These "single" requests & results are the most common protocol messages, and as their names indicates, their payloads follow immediately after the header. For large payloads this can become an issue when dealing with many concurrent requests over a single connection, for which there's a more complicated "streaming" request & result type which we will explore later on.

Faults

There are two types of replies indicating a fault: ErrorResult for requestor faults and RetryResult for responder faults.

If a request is faulty, like missing some required input data or sent over an unauthorized connection, an "error" is send as the reply instead of a regular result:

+------------------ ErrorResult
|   +---------------- requestID   "0001"
|   |       +-------- payloadSize 38
|   |       |
E000100000026{"error":"Unknown operation \"echo\""}

A request that produces an error should not be retried as-is, similar to the 400-class of errors of the HTTP protocol.

In the scenario a fault occurs on the responder side, like suffering a temporary internal error or is unable to complete the request because of resource starvation, a RetryResult is sent as the reply to a request:

+-------------------- RetryResult
|   +------------------ requestID   "0001"
|   |       +---------- wait        0
|   |       |       +-- payloadSize 20
|   |       |       |
e00010000000000000014"service restarting"

In this case โ€” where wait is zero โ€” the requestor is free to retry the request at its convenience.

However in some scenarios the responder might require the requestor to wait for some time before retrying the request, in which case the wait property has a non-zero value:

+-------------------- RetryResult
|   +------------------ requestID   "0001"
|   |       +---------- wait        5000 ms
|   |       |       +-- payloadSize 20
|   |       |       |
e00010000138800000014"request rate limit"

In this case the requestor must not retry the request until at least 5000 milliseconds has passed.

If the protocol communication itself experiences issuesโ€”e.g. an illegal message is receivedโ€”a ProtocolError is written and the connection is closed.

ProtocolError codes:

Code Meaning Comments
0 Abnormal Closed because of an abnormal condition (e.g. server fault, etc)
1 Unsupported protocol The other side does not support the callers protocol
2 Invalid message An invalid message was transmitted
3 Timeout The other side closed the connection because communicating took too long

Example of a peer which does not support the version of the protocol spoken by the sender:

+-------- ProtocolError
|       +-- code 1
|       |
f00000001

Streaming requests and results

For more complicated scenarios there are "streaming-payload" requests and results at our disposal. This allows transmitting of large amounts of data without the need for large buffers. For example this could be used to forward audio data to audio playback hardware, or to transmit a large file off of slow media like a tape drive or hard-disk drive.

Because transmitting a streaming request or result does not occupy "the line" (single-payloads are transmitted serially), they can also be useful when there are many concurrent requests happening over a single connection.

Here's an example of a "streaming-payload" request ...

+------------------ StreamRequest
|   +---------------- requestID   "0001"
|   |      +--------- operation   "echo" (text3Size 4, text3Value "echo")
|   |      |       +- payloadSize 11
|   |      |       |
s0001004echo0000000b{"message":

+------------------ streamReqPart
|   +---------------- requestID   "0001"
|   |       +-------- payloadSize 14
|   |       |
p00010000000e"Hello World"}

+------------------ streamReqPart
|   +---------------- requestID   "0001"
|   |       +-------- payloadSize 0 (end of stream)
|   |       |
p000100000000

... followed by a "streaming-payload" result:

+------------------ StreamResult (1st part)
|   +---------------- requestID   "0001"
|   |       +-------- payloadSize 11
|   |       |
S00010000000b{"message":

+------------------ StreamResult (2nd part)
|   +---------------- requestID   "0001"
|   |       +-------- payloadSize 14
|   |       |
S00010000000e"Hello World"}

+------------------ StreamResult
|   +---------------- requestID   "0001"
|   |       +-------- payloadSize 0 (end of stream)
|   |       |
S000100000000

Streaming requests occupy resources on the responder's side for the duration of the "stream session". Therefore handling of streaming requests should be limited and "RetryResult" used to throttle requests:

+-------------------- RetryResult
|   +------------------ requestID   "0001"
|   |       +---------- wait        5000 ms
|   |       |       +-- payloadSize 19
|   |       |       |
e00010000138800000013"stream rate limit"

This means that the requestor must not send any new requests until wait time has passed.

Notifications

When there's no expectation on a response, Gotalk provides a "notification" message type:

+---------------------- Notification
|              +--------- name        "chat message" (text3Size 12, text3Value "chat message")
|              |       +- payloadSize 46
|              |       |
n00cchat message0000002e{"message":"Hi","from":"nthn","room":"gonuts"}

Notifications are never replied to nor can they cause "error" results. Applications needing acknowledgement of notification delivery might consider using a request instead.

Heartbeats

Because most responders will limit the time it waits for reads, a heartbeat message is send at a certain interval. When a heartbeat is sent is up to the implementation.

A heartbeat contains the sender's local time in the form of an unsigned 32-bit UNIX timestamp. This is enought to cover usage until 2106. I really hope gotalk is nowhere to be found in 2106.

It also contains an optional "load" value, indicating how pressured, or under what load, the sender is. 0 means "idle" and 65535 (0xffff) means "omg I think I'm dying." This can be used to distribute work to less loaded responders in a load-balancing setup.

+------------------ Heartbeat
|   +--------- load 2
|   |       +- time 2015-02-08 22:09:30 UTC
|   |       |
h000254d7de9a

Notes

Requests and results does not need to match on the "single" vs "streaming" detail โ€” it's perfectly fine to send a streaming request and read a single response, or send a single response just to receive a streaming result. The payload type is orthogonal to the message type, with the exception of an error response which is always a "single-payload" message, carrying any information about the error in its payload. Note however that the current version of the Go package does not provide a high-level API for mixed-kind request-response handling.

For transports which might need "heartbeats" to stay alive, like some raw TCP connections over the internet, the suggested way to implement this is by notifications, e.g. send a "heartbeat" notification at a certain interval while no requests are being sent. The Gotalk protocol does not include a "heartbeat" feature because of this reason, as well as the fact that some transports (like web socket) already provide "heartbeat" features.

More Repositories

1

inter

The Inter font family
Python
16,727
star
2

peertalk

iOS and Mac Cocoa library for communicating over USB
Objective-C
3,424
star
3

fb-mac-messenger

โšก๏ธ Mac app wrapping Facebook's Messenger for desktop
Objective-C
2,856
star
4

kod

Programmers' editor for OS X [DEAD PROJECT]
Objective-C
2,296
star
5

node-imagemagick

Imagemagick module for NodeJS โ€” NEW MAINTAINER: @yourdeveloper
JavaScript
1,807
star
6

markdown-wasm

Very fast Markdown parser and HTML generator implemented in WebAssembly, based on md4c
C
1,446
star
7

estrella

Lightweight and versatile build tool based on the esbuild compiler
TypeScript
1,098
star
8

raster

Raster โ€” simple CSS grid system
CSS
806
star
9

js-lru

A fast, simple & universal Least Recently Used (LRU) map for JavaScript
JavaScript
774
star
10

sol

A sunny little virtual machine
C
516
star
11

scrup

Take a screenshot (in OS X) โ€” paste the URL somewhere a second later
Objective-C
405
star
12

chromium-tabs

[historical] Chromium tabs for cocoa applications (project no longer maintained)
Objective-C
388
star
13

wasm-util

WebAssembly utilities
TypeScript
353
star
14

figplug

Figma plugin builder
TypeScript
336
star
15

cocui

Cocoa meets WebKit for more rapid UI development
Objective-C
329
star
16

ec2-webapp

A template I use to quickly set up Node.js-backed web apps on Amazon EC2
324
star
17

llvmbox

Self contained, fully static llvm tools & libs
C
317
star
18

move

A simple, functional-biased, prototypal and powerful programming language that runs on any ES3 (or better) JavaScript platform, aimed toward people new to programming
JavaScript
302
star
19

immutable-cpp

Persistent immutable data structures for C++
C++
281
star
20

rsm

Virtual computer
C
267
star
21

compis

Contemporary systems programming language in the spirit of C
C
196
star
22

uilayer

CALayer-style API for building rich, high-performance UI graphics in WebKit
JavaScript
192
star
23

sublime-theme

My Sublime Text theme
Python
187
star
24

scripter

The Scripter Figma plugin
JavaScript
178
star
25

hue

A functional programming language
C++
170
star
26

gitblog

Git-based blog/cms for PHP, meant as a replacement for Wordpress
PHP
164
star
27

co

A programming language in early development
TypeScript
147
star
28

graphviz

Graphviz web app
JavaScript
118
star
29

LazyDispatch

Thin API and concept on top of libdispatch (aka Grand Central Dispatch) for Cocoa Objective-C code.
Objective-C
102
star
30

afcgi

Asynchronous/multiplexing FastCGI for nginx (incl. ref server implementation)
C
101
star
31

rsms-utils

Collection of CLI programs to help with everyday computer life
Shell
99
star
32

colang

Programming language and compiler โ€”WORK IN PROGRESSโ€”
C
71
star
33

xsys

A well-defined system API for abstracting the OS platform
C
68
star
34

figma-plugins

Collection of Figma plugins
TypeScript
67
star
35

mkweb

simple static website generator
JavaScript
63
star
36

fontkit

JS & WASM library for working with fonts
C
62
star
37

js-object-merge

3-way JavaScript Object merging -- Object.merge(v1, v1a, v1b) -> v2
JavaScript
54
star
38

tc

Tokyo Cabinet Python bindings โ€” In need of a new maintainer
C
54
star
39

smolmsg

Simple messages
Go
54
star
40

js-wasmc

Simplifies building of WebAssembly modules in C/C++ and JS
JavaScript
53
star
41

sigi-pixel-font

Sigi pixel fonts [archived]
52
star
42

WebView-OSX-Screensaver

WebKit web view as a screensaver on OS X
Objective-C
52
star
43

Go.tmbundle

TextMate bundle for the Go programming language
51
star
44

oui

Web-app client-server framework developed as part of dropular.net
JavaScript
49
star
45

wlang

Programming language in development
C
47
star
46

smisk

High performance web service framework, written in C but controlled by Python. Used by Spotify infra 2009โ€“2015.
Python
45
star
47

memex

Software for archiving my digital stuff like tweets
Go
45
star
48

workenv

My personal work environment
Emacs Lisp
44
star
49

ckit

The little C kit
C
44
star
50

dropub

DroPub โ€” drop and publish. Simple OS X MenuItem managing secure transfer of files in the background
Objective-C
42
star
51

serve-http

Simple, safe single-file local web server
JavaScript
42
star
52

go-uuid

Binary sortable universally unique identifier
Go
38
star
53

ghp

Go Hypertext Preprocessor
Go
38
star
54

TypoFig

Mac app for assisting type design in Figma
Objective-C
38
star
55

opencv-face-track-basics

Basic code for tracking faces and eyes using OpenCV
C++
37
star
56

qemu-macos-x86-arm64

Run arm64 Linux Alpine virtualized on macOS x86_64 with QEMU
Shell
35
star
57

tspkg

Create small, fast and easily-distributable packages from TypeScript projects
JavaScript
34
star
58

go-immutable

Immutable data structures for Go
Go
34
star
59

webkit-editor

Experimental text editor which runs in the browser
JavaScript
32
star
60

html5-video

Video player in HTML5
JavaScript
30
star
61

hovden-stitch

A typeface weekend project from 2002 with a classic "stitching"/"embroidery" look
30
star
62

jo

Go-style JavaScript ES6 compiler and packager, based on Babel
JavaScript
30
star
63

libcss-osx

Building libcss as Mac OS X universal binary. Developed as part of Kod (rsms/kod)
Objective-C
29
star
64

tumblr-theme-hunch

The theme used on my blog
28
star
65

dawn-lib

Builds Dawn on Linux and macOS as one single easier-to-use library
Shell
28
star
66

browser-require

CommonJS module require() for web browsers
JavaScript
25
star
67

jsont

A minimal and portable JSON tokenizer for building highly effective and strict parsers (in C and C++)
C
25
star
68

prog-lang-tutorial

JavaScript
25
star
69

node-fsdocs

Simple, ACID and versioned file-system based document database
JavaScript
25
star
70

js-fragment

Client-side templating for modern thinkers
JavaScript
24
star
71

node-couchdb-min

Simplistic CouchDB client with a minimal level of abstraction and connection pooling.
JavaScript
24
star
72

fontctrl

Font manager, keeping font files up to date with a distributed repository model
Go
23
star
73

web-clipboard-promise

Demonstrates lazily-evaluated clipboard data on the Web platform
JavaScript
22
star
74

bezier-tangent

Bรฉzier curve toy
JavaScript
22
star
75

twitter-icon

Alternative icon for Twitter.app
21
star
76

dropular-2010

Redacted snapshot of dropular.net, May 2010
JavaScript
21
star
77

dawn-wire-example

[WIP] Demo of a minimal but functional Dawn-based WebGPU client and server
C++
21
star
78

phpab

Abstract Base โ€“ universal PHP runtime library
PHP
18
star
79

NodeCocoa

Embed node.js in Cocoa or write whole Cocoa apps in node.js
Objective-C
17
star
80

ortho-remote

Some code for playing with the Teenage Engineering Ortho Remote
Objective-C
16
star
81

ml-kern

Kerning done by machines (a project to learn more about ML)
JavaScript
16
star
82

asl-logging

Convenience functions and example code for using ASL (Apple System Log facility)
C
14
star
83

js-miniglob

Minimal glob JavaScript implementation ported from Go's path/filepath
JavaScript
13
star
84

hunch-cocoa

An assortment of Cocoa โ€” mixed extensions and additions to Cocoa
Objective-C
13
star
85

wasm-loader

WebAssembly module loader with import resolution
TypeScript
12
star
86

cgui

super duper simple gui for C, wrapping imgui and stb
C
12
star
87

cmdr

Helps writing command-line programs with subcommands in Go
Go
12
star
88

spotifycocoa

Cocoa framework of libspotify
Objective-C
12
star
89

macfusion

Fork of http://svn.macfusionapp.org/macfusion2/trunk/ โ€” With mainly UI changes like menu item icon and OS-standard volume icons) โ€” Download latest release build: http://cloud.github.com/downloads/rsms/Macfusion/Macfusion.zip
Objective-C
12
star
90

hunch-upload

Multiple concurrent files uploads with progress in pure HTML
JavaScript
11
star
91

functional.js

Work in a functional style with JavaScript and TypeScript
JavaScript
11
star
92

coxlang

Programming language w/ subproject that implements the Go scheduler in C++
C++
11
star
93

lolcatos

The lolcat operating system
Assembly
11
star
94

cometps

Simple comet pub/sub
C
9
star
95

node-imgdb

Image fingerprinting
C++
8
star
96

ssl-client-auth-demo

Demonstrates "client-authenticated TLS handshake"
Shell
8
star
97

connect_facebook

Facebook session support for Connect
8
star
98

mode

Node module manager and repository
JavaScript
8
star
99

flup

Drag-and-drop to quickly put images on Flickr
Objective-C
8
star
100

ipvec

Educational persistent vector implementation in C
C
8
star