While writing [WebSocket TclRFB noVNC on TclHttpd], it seemed a WebSocket to TCP gateway for [noVNC] would be a natural next step. Searching the [noVNC] website a similar application called "websockify" had already been written in Python. Along with "websockify" the noVNC authors also wrote a WebSocket Telnet Client as a proof of concept. The following is the code from the WebSockit2me Starkit available from [http://cloudtk.tcl-lang.org/websockit2me.tml] . See also [CloudTk] It is a WebSocket to TCP gateway built on [TclHttpd] for both [noVNC] and the WebSocket Telnet Client. ====== # Copyright (c) 2015 Jeff Smith # # See the file "license.terms" of TclHttpd for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # I made a few modifications to the Websocket library to make it work with TclHttpd. # # 1. In the procedure ::websocket::takeover changed the following line from # fconfigure $sock -translation binary -blocking on # to # fconfigure $sock -translation binary -blocking off # # # 2. In the procedure ::websocket::Receiver changed the following line from # binary scan $dta Iu mask # to # binary scan $dta I mask # # Without this change the intial handshake with the VNC or Telnet Server # was intermittent ie. did not connect. # # So make the above modifications and then save the following to # WebSocketTCP-gateway.tcl and drop in the custom directory. # # Setup the AuthUserFile and copy the default webmaster credentials to the file # outside the Starkit. if {![file exists $Config(AuthUserFile)]} { set fd [open $Config(AuthUserFile) w] puts $fd "webmaster:$authdefault(user,webmaster)" close $fd unset fd } # If the user is Upgrading noVNC by creating a noVNC directory outside the Starkit, # remap this new directory via Doc_AddRoot. # # The Config(starkitTop) array variable is defined in the main.tcl file of the # Starkit and is used by the startup scripts of TclHttpd to define certain paths. if {[file isdirectory [file join [file dirname $Config(starkitTop)] noVNC]]} { Doc_AddRoot /kanaka/noVNC [file join [file dirname $Config(starkitTop)] noVNC] } else { Doc_AddRoot /kanaka/noVNC [file join $Config(starkitTop) kanaka-noVNC-b804b3e] } Url_AccessInstallPrepend ::websockit2me::AccessHook Url_PrefixInstall /websockit2me [list ::websockit2me::Start /websockit2me] package require websocket namespace eval ::websockit2me { # ensure ::websockit2me namespace exists set ::Config(websockit2meVersion) 0.1.0 } proc ::websockit2me::Start {prefix sock suffix} { upvar #0 Httpd$sock data variable Target set suffix [Url_PathCheck [string trimleft $suffix /]] if {![regexp {.*(/)$} $suffix _ slash]} { set slash "" } if {[info exists ::Session:$suffix]} { return [::websockit2me::Session $sock $suffix] } set noVNCpath {/kanaka/noVNC/vnc.html?path=websockit2me/$session} set Telnetpath {/kanaka/wstelnet.tml?session=$session} switch -- $suffix { "VNC" { ::websockit2me::Dynamic $sock $noVNCpath } "Telnet" { ::websockit2me::Dynamic $sock $Telnetpath } "Vtoken" { ::websockit2me::Token $sock $noVNCpath VNC } "Ttoken" { ::websockit2me::Token $sock $Telnetpath Telnet } default { append pagehtml "
\n" append pagehtml "Enter the VNC Server Host(or IP Address) and the Port you wish to connect too.\n
\n" append pagehtml "
\n" append pagehtml "\nOR\n
\n" append pagehtml "Enter the Telnet Server Host(or IP Address) and the Port you wish to connect too.\n
\n" append pagehtml "
\n" append pagehtml "