Initial commit
This commit is contained in:
commit
aa3b3a4375
|
@ -0,0 +1,3 @@
|
|||
src/
|
||||
.history/
|
||||
*.exe
|
|
@ -0,0 +1,15 @@
|
|||
# Yealink-Remote
|
||||
|
||||
**GO Workspace aktualisieren und abhängige Pakete herunterladen**
|
||||
|
||||
Linux: `go get`
|
||||
|
||||
Windows (VSCode Terminal): `$env:GOOS="windows"; $env:GOARCH="amd64"; $env:GOROOT="E:\go"; $env:CGO_ENABLED=0; $env:GOPATH="F:\git_masilux_de\YealinkRemote"; go get`
|
||||
|
||||
|
||||
**Programm kompilieren**
|
||||
|
||||
Linux: `go build -o YealinkRemote .`
|
||||
|
||||
Windows: `$env:GOOS="windows"; $env:GOARCH="amd64"; $env:GOROOT="E:\go"; $env:CGO_ENABLED=0; $env:GOPATH="F:\git_masilux_de\YealinkRemote"; go build -o YealinkRemote.exe .`
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/surgemq/surgemq/service"
|
||||
)
|
||||
|
||||
var StartUpPath string
|
||||
|
||||
// our main function
|
||||
func main() {
|
||||
|
||||
// StartupPath auslesen
|
||||
dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
StartUpPath = dir
|
||||
|
||||
fmt.Println("-----------------------------------------------")
|
||||
fmt.Println("Escape Room 0.3")
|
||||
fmt.Println("-----------------------------------------------")
|
||||
fmt.Println("Webserver: http://*:8000")
|
||||
fmt.Println("MQTT-Server: tcp://*:1833")
|
||||
fmt.Println("Websocket-Server: http://*:8081")
|
||||
fmt.Println("-----------------------------------------------")
|
||||
fmt.Println("Admin-Seite: http://127.0.0.1:8000/admin.html")
|
||||
fmt.Println("-----------------------------------------------")
|
||||
fmt.Println("")
|
||||
|
||||
// Create a new mqtt server
|
||||
svr := &service.Server{
|
||||
KeepAlive: 300, // seconds
|
||||
ConnectTimeout: 2, // seconds
|
||||
SessionsProvider: "mem", // keeps sessions in memory
|
||||
Authenticator: "mockSuccess", // always succeed
|
||||
TopicsProvider: "mem", // keeps topic subscriptions in memory
|
||||
}
|
||||
|
||||
// Websocket
|
||||
addr := "tcp://:1883"
|
||||
AddWebsocketHandler("/mqtt", addr)
|
||||
go ListenAndServeWebsocket(":8081")
|
||||
|
||||
// Listen and serve connections at localhost:1883
|
||||
go svr.ListenAndServe("tcp://:1883")
|
||||
|
||||
router := mux.NewRouter()
|
||||
//router.HandleFunc("/api/folder", GetFolderContent).Methods("GET")
|
||||
router.HandleFunc("/api/folder/{foldername:.*}", GetFolderContent).Methods("GET")
|
||||
//router.HandleFunc("/api/image/{imagename:.*}", GetImage).Methods("GET")
|
||||
|
||||
//-------------------------------------------
|
||||
router.HandleFunc("/api/sendkey/{ip}/{key}", GetSendKey).Methods("GET")
|
||||
//-------------------------------------------
|
||||
|
||||
router.PathPrefix("/").Handler(http.FileServer(http.Dir("./web"))).Methods("GET")
|
||||
log.Fatal(http.ListenAndServe(":8000", router))
|
||||
|
||||
}
|
||||
|
||||
func GetSendKey(w http.ResponseWriter, r *http.Request) {
|
||||
params := mux.Vars(r)
|
||||
pIP := params["ip"]
|
||||
pKey := params["key"]
|
||||
|
||||
resp, err := http.Get("http://admin:admin@" + pIP + "/servlet?key=" + pKey)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
|
||||
json.NewEncoder(w).Encode(body)
|
||||
}
|
||||
|
||||
func GetFolderContent(w http.ResponseWriter, r *http.Request) {
|
||||
// http://127.0.0.1:8000/api/folder/1080_stahlwerke
|
||||
|
||||
params := mux.Vars(r)
|
||||
pFolder := params["foldername"]
|
||||
fmt.Println(path.Join(StartUpPath, "web", pFolder))
|
||||
files, err := ioutil.ReadDir(path.Join(StartUpPath, "web", pFolder))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
var dateien []string
|
||||
for _, f := range files {
|
||||
dateien = append(dateien, f.Name())
|
||||
}
|
||||
|
||||
json.NewEncoder(w).Encode(dateien)
|
||||
}
|
||||
|
||||
func isDir(name string) bool {
|
||||
var ret bool
|
||||
fi, err := os.Stat(name)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if fi.IsDir() {
|
||||
ret = true
|
||||
} else {
|
||||
ret = false
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
/*
|
||||
func GetMem(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var m runtime.MemStats
|
||||
runtime.ReadMemStats(&m)
|
||||
log.Printf("\nAlloc = %v\nTotalAlloc = %v\nSys = %v\nNumGC = %v\n\n", m.Alloc/1024, m.TotalAlloc/1024, m.Sys/1024, m.NumGC)
|
||||
|
||||
json.NewEncoder(w).Encode(m)
|
||||
|
||||
PrintMemUsage()
|
||||
|
||||
}
|
||||
|
||||
func PrintMemUsage() {
|
||||
var m runtime.MemStats
|
||||
runtime.ReadMemStats(&m)
|
||||
// For info on each, see: https://golang.org/pkg/runtime/#MemStats
|
||||
fmt.Printf("Alloc = %v MiB", bToMb(m.Alloc))
|
||||
fmt.Printf("\tTotalAlloc = %v MiB", bToMb(m.TotalAlloc))
|
||||
fmt.Printf("\tSys = %v MiB", bToMb(m.Sys))
|
||||
fmt.Printf("\tNumGC = %v\n", m.NumGC)
|
||||
}
|
||||
|
||||
func bToMb(b uint64) uint64 {
|
||||
return b / 1024 / 1024
|
||||
}
|
||||
|
||||
*/
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,200 @@
|
|||
/* http://github.com/mindmup/bootstrap-wysiwyg */
|
||||
/*global jQuery, $, FileReader*/
|
||||
/*jslint browser:true*/
|
||||
(function ($) {
|
||||
'use strict';
|
||||
var readFileIntoDataUrl = function (fileInfo) {
|
||||
var loader = $.Deferred(),
|
||||
fReader = new FileReader();
|
||||
fReader.onload = function (e) {
|
||||
loader.resolve(e.target.result);
|
||||
};
|
||||
fReader.onerror = loader.reject;
|
||||
fReader.onprogress = loader.notify;
|
||||
fReader.readAsDataURL(fileInfo);
|
||||
return loader.promise();
|
||||
};
|
||||
$.fn.cleanHtml = function () {
|
||||
var html = $(this).html();
|
||||
return html && html.replace(/(<br>|\s|<div><br><\/div>| )*$/, '');
|
||||
};
|
||||
$.fn.wysiwyg = function (userOptions) {
|
||||
var editor = this,
|
||||
selectedRange,
|
||||
options,
|
||||
toolbarBtnSelector,
|
||||
updateToolbar = function () {
|
||||
if (options.activeToolbarClass) {
|
||||
$(options.toolbarSelector).find(toolbarBtnSelector).each(function () {
|
||||
var command = $(this).data(options.commandRole);
|
||||
if (document.queryCommandState(command)) {
|
||||
$(this).addClass(options.activeToolbarClass);
|
||||
} else {
|
||||
$(this).removeClass(options.activeToolbarClass);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
execCommand = function (commandWithArgs, valueArg) {
|
||||
var commandArr = commandWithArgs.split(' '),
|
||||
command = commandArr.shift(),
|
||||
args = commandArr.join(' ') + (valueArg || '');
|
||||
document.execCommand(command, 0, args);
|
||||
updateToolbar();
|
||||
},
|
||||
bindHotkeys = function (hotKeys) {
|
||||
$.each(hotKeys, function (hotkey, command) {
|
||||
editor.keydown(hotkey, function (e) {
|
||||
if (editor.attr('contenteditable') && editor.is(':visible')) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
execCommand(command);
|
||||
}
|
||||
}).keyup(hotkey, function (e) {
|
||||
if (editor.attr('contenteditable') && editor.is(':visible')) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
getCurrentRange = function () {
|
||||
var sel = window.getSelection();
|
||||
if (sel.getRangeAt && sel.rangeCount) {
|
||||
return sel.getRangeAt(0);
|
||||
}
|
||||
},
|
||||
saveSelection = function () {
|
||||
selectedRange = getCurrentRange();
|
||||
},
|
||||
restoreSelection = function () {
|
||||
var selection = window.getSelection();
|
||||
if (selectedRange) {
|
||||
try {
|
||||
selection.removeAllRanges();
|
||||
} catch (ex) {
|
||||
document.body.createTextRange().select();
|
||||
document.selection.empty();
|
||||
}
|
||||
|
||||
selection.addRange(selectedRange);
|
||||
}
|
||||
},
|
||||
insertFiles = function (files) {
|
||||
editor.focus();
|
||||
$.each(files, function (idx, fileInfo) {
|
||||
if (/^image\//.test(fileInfo.type)) {
|
||||
$.when(readFileIntoDataUrl(fileInfo)).done(function (dataUrl) {
|
||||
execCommand('insertimage', dataUrl);
|
||||
}).fail(function (e) {
|
||||
options.fileUploadError("file-reader", e);
|
||||
});
|
||||
} else {
|
||||
options.fileUploadError("unsupported-file-type", fileInfo.type);
|
||||
}
|
||||
});
|
||||
},
|
||||
markSelection = function (input, color) {
|
||||
restoreSelection();
|
||||
if (document.queryCommandSupported('hiliteColor')) {
|
||||
document.execCommand('hiliteColor', 0, color || 'transparent');
|
||||
}
|
||||
saveSelection();
|
||||
input.data(options.selectionMarker, color);
|
||||
},
|
||||
bindToolbar = function (toolbar, options) {
|
||||
toolbar.find(toolbarBtnSelector).click(function () {
|
||||
restoreSelection();
|
||||
editor.focus();
|
||||
execCommand($(this).data(options.commandRole));
|
||||
saveSelection();
|
||||
});
|
||||
toolbar.find('[data-toggle=dropdown]').click(restoreSelection);
|
||||
|
||||
toolbar.find('input[type=text][data-' + options.commandRole + ']').on('webkitspeechchange change', function () {
|
||||
var newValue = this.value; /* ugly but prevents fake double-calls due to selection restoration */
|
||||
this.value = '';
|
||||
restoreSelection();
|
||||
if (newValue) {
|
||||
editor.focus();
|
||||
execCommand($(this).data(options.commandRole), newValue);
|
||||
}
|
||||
saveSelection();
|
||||
}).on('focus', function () {
|
||||
var input = $(this);
|
||||
if (!input.data(options.selectionMarker)) {
|
||||
markSelection(input, options.selectionColor);
|
||||
input.focus();
|
||||
}
|
||||
}).on('blur', function () {
|
||||
var input = $(this);
|
||||
if (input.data(options.selectionMarker)) {
|
||||
markSelection(input, false);
|
||||
}
|
||||
});
|
||||
toolbar.find('input[type=file][data-' + options.commandRole + ']').change(function () {
|
||||
restoreSelection();
|
||||
if (this.type === 'file' && this.files && this.files.length > 0) {
|
||||
insertFiles(this.files);
|
||||
}
|
||||
saveSelection();
|
||||
this.value = '';
|
||||
});
|
||||
},
|
||||
initFileDrops = function () {
|
||||
editor.on('dragenter dragover', false)
|
||||
.on('drop', function (e) {
|
||||
var dataTransfer = e.originalEvent.dataTransfer;
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
if (dataTransfer && dataTransfer.files && dataTransfer.files.length > 0) {
|
||||
insertFiles(dataTransfer.files);
|
||||
}
|
||||
});
|
||||
};
|
||||
options = $.extend({}, $.fn.wysiwyg.defaults, userOptions);
|
||||
toolbarBtnSelector = 'a[data-' + options.commandRole + '],button[data-' + options.commandRole + '],input[type=button][data-' + options.commandRole + ']';
|
||||
bindHotkeys(options.hotKeys);
|
||||
if (options.dragAndDropImages) {
|
||||
initFileDrops();
|
||||
}
|
||||
bindToolbar($(options.toolbarSelector), options);
|
||||
editor.attr('contenteditable', true)
|
||||
.on('mouseup keyup mouseout', function () {
|
||||
saveSelection();
|
||||
updateToolbar();
|
||||
});
|
||||
$(window).bind('touchend', function (e) {
|
||||
var isInside = (editor.is(e.target) || editor.has(e.target).length > 0),
|
||||
currentRange = getCurrentRange(),
|
||||
clear = currentRange && (currentRange.startContainer === currentRange.endContainer && currentRange.startOffset === currentRange.endOffset);
|
||||
if (!clear || isInside) {
|
||||
saveSelection();
|
||||
updateToolbar();
|
||||
}
|
||||
});
|
||||
return this;
|
||||
};
|
||||
$.fn.wysiwyg.defaults = {
|
||||
hotKeys: {
|
||||
'ctrl+b meta+b': 'bold',
|
||||
'ctrl+i meta+i': 'italic',
|
||||
'ctrl+u meta+u': 'underline',
|
||||
'ctrl+z meta+z': 'undo',
|
||||
'ctrl+y meta+y meta+shift+z': 'redo',
|
||||
'ctrl+l meta+l': 'justifyleft',
|
||||
'ctrl+r meta+r': 'justifyright',
|
||||
'ctrl+e meta+e': 'justifycenter',
|
||||
'ctrl+j meta+j': 'justifyfull',
|
||||
'shift+tab': 'outdent',
|
||||
'tab': 'indent'
|
||||
},
|
||||
toolbarSelector: '[data-role=editor-toolbar]',
|
||||
commandRole: 'edit',
|
||||
activeToolbarClass: 'btn-info',
|
||||
selectionMarker: 'edit-focus-marker',
|
||||
selectionColor: 'darkgrey',
|
||||
dragAndDropImages: true,
|
||||
fileUploadError: function (reason, detail) { console.log("File upload error", reason, detail); }
|
||||
};
|
||||
}(window.jQuery));
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,93 @@
|
|||
body {
|
||||
font-size: .875rem;
|
||||
}
|
||||
|
||||
.feather {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sidebar
|
||||
*/
|
||||
|
||||
.sidebar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 100; /* Behind the navbar */
|
||||
padding: 0;
|
||||
box-shadow: inset -1px 0 0 rgba(0, 0, 0, .1);
|
||||
}
|
||||
|
||||
.sidebar-sticky {
|
||||
position: -webkit-sticky;
|
||||
position: sticky;
|
||||
top: 48px; /* Height of navbar */
|
||||
height: calc(100vh - 48px);
|
||||
padding-top: .5rem;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */
|
||||
}
|
||||
|
||||
.sidebar .nav-link {
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.sidebar .nav-link .feather {
|
||||
margin-right: 4px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.sidebar .nav-link.active {
|
||||
color: #007bff;
|
||||
}
|
||||
|
||||
.sidebar .nav-link:hover .feather,
|
||||
.sidebar .nav-link.active .feather {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.sidebar-heading {
|
||||
font-size: .75rem;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
/*
|
||||
* Navbar
|
||||
*/
|
||||
|
||||
.navbar-brand {
|
||||
padding-top: .75rem;
|
||||
padding-bottom: .75rem;
|
||||
font-size: 1rem;
|
||||
background-color: rgba(0, 0, 0, .25);
|
||||
box-shadow: inset -1px 0 0 rgba(0, 0, 0, .25);
|
||||
}
|
||||
|
||||
.navbar .form-control {
|
||||
padding: .75rem 1rem;
|
||||
border-width: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.form-control-dark {
|
||||
color: #fff;
|
||||
background-color: rgba(255, 255, 255, .1);
|
||||
border-color: rgba(255, 255, 255, .1);
|
||||
}
|
||||
|
||||
.form-control-dark:focus {
|
||||
border-color: transparent;
|
||||
box-shadow: 0 0 0 3px rgba(255, 255, 255, .25);
|
||||
}
|
||||
|
||||
/*
|
||||
* Utilities
|
||||
*/
|
||||
|
||||
.border-top { border-top: 1px solid #e5e5e5; }
|
||||
.border-bottom { border-bottom: 1px solid #e5e5e5; }
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,79 @@
|
|||
<html>
|
||||
<head>
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" type="text/javascript"></script>
|
||||
<!--
|
||||
<script src="http://www.hivemq.com/demos/websocket-client/js/mqttws31.js" type="text/javascript"></script>
|
||||
<script src="/mqtt.js"></script>
|
||||
-->
|
||||
<style>
|
||||
.center {
|
||||
margin: auto;
|
||||
width: 80%;
|
||||
border: 3px solid white;
|
||||
padding: 10px;
|
||||
background-color: rgba(200, 200, 200, 0.8);
|
||||
font-family: Verdana, Helvetica, sans-serif;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
var room = "raum1";
|
||||
var Countdown;
|
||||
|
||||
function SendKey(key) {
|
||||
|
||||
$.ajax({
|
||||
crossDomain: true,
|
||||
method: "GET",
|
||||
contentType:'text/html; charset=utf-8',
|
||||
url: 'http://127.0.0.1:8000/api/sendkey/10.25.176.35/'+key,
|
||||
//dataType: "json",
|
||||
success: function(content){
|
||||
//$(screenshot).html("nix");
|
||||
//$(screenshot).html("<img src='http://10.25.176.35/servlet?command=screenshot'>");
|
||||
$(screenshot).html("<img src='http://10.25.176.35/servlet?command=screenshot&dt="+new Date().getTime()+"'>");
|
||||
},
|
||||
error: function (xhr, ajaxOptions, thrownError) {
|
||||
console.log(xhr);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
//client.connect(options);
|
||||
|
||||
$(screenshot).html("<img src='http://10.25.176.35/servlet?command=screenshot'>");
|
||||
|
||||
|
||||
/*
|
||||
setInterval(function(){
|
||||
$(screenshot).html("<img src='http://10.25.176.35/servlet?command=screenshot&dt="+new Date().getTime()+"'>");
|
||||
console.log("<img src='http://10.25.176.35/servlet?command=screenshot&dt="+new Date().getTime()+"'>");
|
||||
},2000);
|
||||
*/
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="screenshot" class="center"></div>
|
||||
|
||||
<center>
|
||||
<button id="btn_menu" onclick="SendKey('MENU')">MENU</button>
|
||||
<button id="btn_ok" onclick="SendKey('OK')">OK</button>
|
||||
<button id="btn_esc" onclick="SendKey('CANCEL')">ESC</button>
|
||||
<br>
|
||||
<button id="btn_LEFT" onclick="SendKey('LEFT')">LEFT</button>
|
||||
<button id="btn_RIGHT" onclick="SendKey('RIGHT')">RIGHT</button>
|
||||
<button id="btn_UP" onclick="SendKey('UP')">UP</button>
|
||||
<button id="btn_DOWN" onclick="SendKey('DOWN')">DOWN</button>
|
||||
</center>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,102 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/surge/glog"
|
||||
"golang.org/x/net/websocket"
|
||||
)
|
||||
|
||||
func DefaultListenAndServeWebsocket() error {
|
||||
if err := AddWebsocketHandler("/mqtt", "test.mosquitto.org:1883"); err != nil {
|
||||
return err
|
||||
}
|
||||
return ListenAndServeWebsocket(":1234")
|
||||
}
|
||||
|
||||
func AddWebsocketHandler(urlPattern string, uri string) error {
|
||||
glog.Debugf("AddWebsocketHandler urlPattern=%s, uri=%s", urlPattern, uri)
|
||||
u, err := url.Parse(uri)
|
||||
if err != nil {
|
||||
glog.Errorf("surgemq/main: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
h := func(ws *websocket.Conn) {
|
||||
WebsocketTcpProxy(ws, u.Scheme, u.Host)
|
||||
}
|
||||
http.Handle(urlPattern, websocket.Handler(h))
|
||||
return nil
|
||||
}
|
||||
|
||||
/* start a listener that proxies websocket <-> tcp */
|
||||
func ListenAndServeWebsocket(addr string) error {
|
||||
return http.ListenAndServe(addr, nil)
|
||||
}
|
||||
|
||||
/* starts an HTTPS listener */
|
||||
func ListenAndServeWebsocketSecure(addr string, cert string, key string) error {
|
||||
return http.ListenAndServeTLS(addr, cert, key, nil)
|
||||
}
|
||||
|
||||
/* copy from websocket to writer, this copies the binary frames as is */
|
||||
func io_copy_ws(src *websocket.Conn, dst io.Writer) (int, error) {
|
||||
var buffer []byte
|
||||
count := 0
|
||||
for {
|
||||
err := websocket.Message.Receive(src, &buffer)
|
||||
if err != nil {
|
||||
return count, err
|
||||
}
|
||||
n := len(buffer)
|
||||
count += n
|
||||
i, err := dst.Write(buffer)
|
||||
if err != nil || i < 1 {
|
||||
return count, err
|
||||
}
|
||||
}
|
||||
return count, nil
|
||||
}
|
||||
|
||||
/* copy from reader to websocket, this copies the binary frames as is */
|
||||
func io_ws_copy(src io.Reader, dst *websocket.Conn) (int, error) {
|
||||
buffer := make([]byte, 2048)
|
||||
count := 0
|
||||
for {
|
||||
n, err := src.Read(buffer)
|
||||
if err != nil || n < 1 {
|
||||
return count, err
|
||||
}
|
||||
count += n
|
||||
err = websocket.Message.Send(dst, buffer[0:n])
|
||||
if err != nil {
|
||||
return count, err
|
||||
}
|
||||
}
|
||||
return count, nil
|
||||
}
|
||||
|
||||
/* handler that proxies websocket <-> unix domain socket */
|
||||
func WebsocketTcpProxy(ws *websocket.Conn, nettype string, host string) error {
|
||||
client, err := net.Dial(nettype, host)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer client.Close()
|
||||
defer ws.Close()
|
||||
chDone := make(chan bool)
|
||||
|
||||
go func() {
|
||||
io_ws_copy(client, ws)
|
||||
chDone <- true
|
||||
}()
|
||||
go func() {
|
||||
io_copy_ws(ws, client)
|
||||
chDone <- true
|
||||
}()
|
||||
<-chDone
|
||||
return nil
|
||||
}
|
Loading…
Reference in New Issue