https://github.com/schmichael/whispering-gophers
A whispernet written in Go. Continued from Google's excellent code lab: https://code.google.com/p/whispering-gophers/
https://github.com/schmichael/whispering-gophers
Last synced: about 1 year ago
JSON representation
A whispernet written in Go. Continued from Google's excellent code lab: https://code.google.com/p/whispering-gophers/
- Host: GitHub
- URL: https://github.com/schmichael/whispering-gophers
- Owner: schmichael
- Created: 2013-11-21T00:38:53.000Z (over 12 years ago)
- Default Branch: master
- Last Pushed: 2015-02-13T04:34:20.000Z (over 11 years ago)
- Last Synced: 2025-03-25T14:21:43.516Z (about 1 year ago)
- Language: Go
- Size: 240 KB
- Stars: 20
- Watchers: 0
- Forks: 18
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
Whispering Gophers
==================
A whispernet written in Go.
Based on: https://code.google.com/p/whispering-gophers/
Getting Started
---------------
If you have not worked in GO before (i.e., don't have a GOPATH), then start here:
```
mkdir ~/somedir
cd somedir
export GOPATH=~/somedir
git clone https://github.com/pdxgo/whispering-gophers.git
go get github.com/pdxgo/whispering-gophers
cd whispering-gophers
go build
```
Running
-------
For the first peer:
```sh
go run main.go -nick phil
```
Next peers:
```sh
go run main.go -peer $IP_OF_PEER:55555 -nick goldy
```
Where ``$IP_OF_PEER`` is the IP address printed by a running peer.
Protocol
--------
*Peers* are long running programs which accept user input and display messages
from other peers. At the minimum a well participating peer must:
* Manually connect to at least 1 peer
* Bind to an address and accept connections from any peer
*Messages* should be of the form:
```json
{
"ID": "",
"Addr": "",
"Body": ""
}
```
*Peers* should follow the following behavior with regard to *messages*:
* Display messages (``Body`` key) from other peers
* Disconnect peers which send malformed messages
* Accept user input as ``Body`` content
* Send messages to all known peers.
* When sending messages ``Addr`` must be the ``IP:Port`` combination the peer
is listening on.
* Connect to new peers seen in ``Addr`` fields of received messages
* Broadcast all messages to all peers (except ``Addr``); store list of Seen
messages by ID to avoid rebroadcasting
* Payloads without a ``Body`` and/or with unknown keys should be silently
*ignored* to support extensions
* *Messages are* **not** *delimited or framed.* Multiple messages *may* be sent
across a single connection. Peers recieving messages *must* detect the end of
the JSON object to know when one message ends and another may begin.
Connections are unidirectional. In a healthy whispernet each peer will have 1
outgoing connection to send messages to every other peer, as well as 1 incoming
connection from each peer for receiving messages.
Extensions
----------
Roughly ordered based on difficulty.
1. ~~Pretty display messages~~ Done!
1. ~~Nicks!~~ Done!
1. Forget old message IDs (the basic daemon slowly uses all memory) - may use
*Timestamp* field - see below
1. Base ID on hash of Addr + Body + Timestamp - see below
1. Discover based on [UDP
broadcasts](https://groups.google.com/d/msg/golang-nuts/nbmYWwHCgPc/ZBw2uH6Bdi4J)
See below - *Partially done*
1. Build web interface into daemon
1. Simple input form (textbox + submit button)
1. Chat output (refreshed on a timer or using
[websockets](http://godoc.org/code.google.com/p/go.net/websocket) if you're
really fancy)
1. Peer connection controls (connect to a new host, disconnect from a host)
1. File transfers - see below
1. Send backlog to newly connected peers - see backlog below
1. Flood control: Disconnect and blacklist peers whose activity exceeds a
threshold
1. PKI all the things
1. Scalable routing
**UDP Broadcast Protocol**
Broadcasts should be of the form: "IP:PORT" (same as ``Addr``) and may be sent on
behalf of any peers.
**Timestamp field**
To support various features, messages should include an optional Timestamp
field of the format milliseconds since UNIX epoch as a number. For example:
```json
{
"ID": "abc123",
"Addr": "192.168.1.53:2345",
"Body": "Hello world!",
"Timestamp": 1382050782085
}
```
**Hashed ID field**
To support very rudimentary payload verification, use a hash of the concatenated Addr, Body, and Timestamp fields. To allow backward compatibility with old clients, hashed IDs should be of the form:
```json
{
"ID": "hash:sha256:",
...
}
```
Where each string starts with "hash:" followed by the name of the hash function used, followed by a colon and the hex encoded hash.
Unknown hash functions should cause the reader to revert to the basic random-string-ID behavior.
Peers should drop messages whose hashes don't match the current message payload.
**File transfers**
Two new keys: "FileType" and "FileContents"
* *FileType* should be the MIME type like: "image/gif"
* *FileContents* should be the Base64 encoded file contents
**Backlog**
Upon receiving a new connection from a peer, a daemon should replay that peer the last N messages (the actual number shouldn't be important) to the peer.