Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Added Go server
The code is from http://code.google.com/p/webrtc-datachannel-polyfill developed by Alfred Knallfred Godoy (alfred.knallfred.godoy@gmail.com), but I bet that his polyfill implementation was stoled from mine... It's not normal that has the same structure and also almost the same vars names...
- Loading branch information
Showing
2 changed files
with
253 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
(function() { | ||
|
||
var | ||
// Configuration: | ||
hostname = window.CHANNEL_HOST || window.location.host || 'localhost:8000', | ||
websocketServer = "ws://"+hostname+"/", | ||
|
||
// For browser compatibility: | ||
PeerConnection = window.PeerConnection | ||
|| window.RTCPeerConnection | ||
|| window.mozPeerConnection | ||
|| window.webkitRTCPeerConnection | ||
|| window.webkitPeerConnection00; | ||
|
||
if (typeof(PeerConnection) === 'undefined') { | ||
console.error('Your browser does not support PeerConnection.'); | ||
return; | ||
} | ||
|
||
var pc = new PeerConnection(null); | ||
|
||
if (typeof(pc.createDataChannel) !== 'undefined') { | ||
try { | ||
// This will throw when data channels is not implemented properly yet | ||
pc.createDataChannel('polyfill') | ||
|
||
// If we get this far you already have DataChannel support. | ||
return console.log('REAL DATACHANNELS!'); | ||
} catch(e){ | ||
// TODO verify the Error | ||
} | ||
} | ||
|
||
function DataChannel(peerConnection,label,dataChannelDict) { | ||
this.readyState = "connecting"; | ||
this.label = label; | ||
this.reliable = (!dataChannelDict || !dataChannelDict.reliable); | ||
this._peerConnection = peerConnection; | ||
this._queue = []; | ||
this._webSocket = new WebSocket(websocketServer); | ||
|
||
this._webSocket.onclose = function() { | ||
this.readyState = "closed"; | ||
if (typeof this.onclose == 'function'){ | ||
this.onclose() | ||
} | ||
}.bind(this); | ||
|
||
this._webSocket.onopen = function() { | ||
this.readyState = "open"; | ||
this._identify(); | ||
|
||
if (typeof this.onopen == 'function'){ | ||
this.onopen() | ||
} | ||
|
||
if (typeof this._peerConnection.ondatachannel == 'function') { | ||
var evt = document.createEvent('Event') | ||
evt.initEvent('datachannel', true, true) | ||
evt.channel = this; | ||
this._peerConnection.ondatachannel(evt) | ||
} | ||
|
||
// empty the queue | ||
while(this._queue.length) { | ||
data = this._queue.shift(); | ||
this.send(data); | ||
} | ||
}.bind(this); | ||
|
||
this._webSocket.onmessage = function(msg) { | ||
if (typeof this.onmessage == 'function') { | ||
this.onmessage(msg); | ||
} | ||
}.bind(this); | ||
|
||
this._webSocket.onerror = function(msg) { | ||
console.error(msg) | ||
if (typeof this.onerror == 'function') { | ||
this.onerror(msg); | ||
} | ||
}.bind(this); | ||
}; | ||
|
||
DataChannel.prototype._identify = function() { | ||
if (this._peerConnection === null) return false; | ||
|
||
if (this._peerConnection._localDescription && this._peerConnection._remoteDescription) { | ||
this._localId = description2id(this._peerConnection._localDescription) + '_' + this.label | ||
this._remoteId = description2id(this._peerConnection._remoteDescription) + '_' + this.label | ||
this.send('connect:' + this._localId + ':' + this._remoteId ); | ||
} | ||
}; | ||
|
||
DataChannel.prototype.close = function() { | ||
this.readyState = "closing"; | ||
this._webSocket.close(); | ||
}; | ||
|
||
DataChannel.prototype.send = function(data) { | ||
if( this.readyState == 'open' ) { | ||
this._webSocket.send(data); | ||
} else if( this.reliable ) { // queue messages when "reliable" | ||
this._queue.push(data); | ||
} | ||
}; | ||
|
||
PeerConnection.prototype.createDataChannel = function(label, dataChannelDict) { | ||
console.log('createDataChannel',label,dataChannelDict) | ||
var channel = new DataChannel(this,label,dataChannelDict); | ||
|
||
if (typeof(this._allDataChannels) == 'undefined') { | ||
this._allDataChannels = []; | ||
} | ||
this._allDataChannels.push(channel); | ||
|
||
return channel; | ||
} | ||
|
||
function description2id(description) { | ||
var result = description.sdp.replace(/(\r\n|\n|\r)/gm, '\n') | ||
var re = new RegExp("o=.+"); | ||
result = re.exec(result) | ||
return result[0] | ||
} | ||
|
||
// Overwrite PeerConnection's description setters, to get ID:s for the websocket connections. | ||
|
||
var | ||
setLocalDescription = PeerConnection.prototype.setLocalDescription, | ||
setRemoteDescription = PeerConnection.prototype.setRemoteDescription; | ||
|
||
PeerConnection.prototype.setLocalDescription = function(description, successCallback, errorCallback) { | ||
this._localDescription = description; | ||
if (typeof(this._allDataChannels) != 'undefined') { | ||
for (var i in this._allDataChannels) { | ||
this._allDataChannels[i]._identify(); | ||
} | ||
} | ||
setLocalDescription.apply(this, arguments); | ||
}; | ||
|
||
PeerConnection.prototype.setRemoteDescription = function(description) { | ||
this._remoteDescription = description; | ||
if (typeof(this._allDataChannels) != 'undefined') { | ||
for (var i in this._allDataChannels) { | ||
this._allDataChannels[i]._identify(); | ||
} | ||
}; | ||
setRemoteDescription.apply(this, arguments); | ||
}; | ||
|
||
}()); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"net/http" | ||
"code.google.com/p/go.net/websocket" | ||
"strings" | ||
) | ||
|
||
// =================== | ||
// C O N N E C T I O N | ||
// =================== | ||
|
||
type connection struct { | ||
// The websocket connection. | ||
ws *websocket.Conn | ||
|
||
id string | ||
|
||
peer *connection | ||
|
||
// Buffered channel of outbound messages. | ||
send chan string | ||
} | ||
|
||
var connections map[string]*connection = make(map[string]*connection) | ||
|
||
func (c *connection) reader() { | ||
for { | ||
|
||
fmt.Println(len(connections)) | ||
|
||
var message string | ||
err := websocket.Message.Receive(c.ws, &message) | ||
if err != nil { | ||
fmt.Println(err) | ||
break | ||
} | ||
|
||
fmt.Println("R: " + c.id + " : " + message) | ||
|
||
if len(message) > 7 && message[0:8] == "connect:" { | ||
{ | ||
connectParts := strings.Split(message, ":") | ||
if len(connectParts) == 3 { | ||
c.id = connectParts[1] | ||
connections[c.id] = c | ||
|
||
if _,ok := connections[connectParts[2]]; ok { | ||
c.peer = connections[connectParts[2]] | ||
connections[connectParts[2]].peer = c | ||
} | ||
} | ||
} | ||
} else if (c.peer != nil) { | ||
|
||
c.peer.send <- message | ||
|
||
} | ||
|
||
} | ||
c.send <- "disconnect" // Send disconnect to my own writer. | ||
delete(connections, c.id) // Remove myself from connection map. | ||
fmt.Println("R: Connection lost:" + c.id) | ||
c.ws.Close() | ||
} | ||
|
||
func (c *connection) writer() { | ||
for { | ||
message := <- c.send | ||
if message == "disconnect" { | ||
break; | ||
} | ||
fmt.Println("W: " + c.id + " : " + message) | ||
err := websocket.Message.Send(c.ws, message) | ||
if err != nil { | ||
break | ||
} | ||
} | ||
fmt.Println("W: Connection lost:" + c.id) | ||
c.ws.Close() | ||
} | ||
|
||
// ======= | ||
// M A I N | ||
// ======= | ||
|
||
func wsHandler(ws *websocket.Conn) { | ||
fmt.Println("NEW WEBSOCKET!"); | ||
fmt.Println(ws.Config()) | ||
fmt.Println(ws.RemoteAddr()) | ||
c := &connection{send: make(chan string, 256), ws: ws} | ||
go c.writer() | ||
c.reader() | ||
} | ||
|
||
func main() { | ||
http.Handle("/", websocket.Handler(wsHandler)); | ||
http.ListenAndServe(":8000", nil) | ||
} |