Created
June 14, 2015 07:13
-
-
Save tomsmeding/493e9930411dcf021c9e to your computer and use it in GitHub Desktop.
Simple wscat implementation that works. The npm wscat uses readline a bit strangely.
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
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<title>wscat</title> | |
<script> | |
var address="",conn=null; | |
var inputhistory=[],historyidx=null,droppedCurrent=null; | |
function log(src,s){ | |
var tr,td; | |
tr=document.createElement("tr"); | |
td=document.createElement("td"); | |
td.appendChild(document.createTextNode(src)); | |
tr.appendChild(td); | |
td=document.createElement("td"); | |
td.appendChild(document.createTextNode(s)); | |
tr.appendChild(td); | |
var wslog=document.getElementById("wslog"); | |
wslog.appendChild(tr); | |
wslog.scrollTop=wslog.scrollHeight; | |
var lastlog=wslog.children[wslog.children.length-1]; | |
if(lastlog.scrollIntoView)lastlog.scrollIntoView(); | |
} | |
function reconnect(){ | |
if(address==""){ | |
log("","Cannot connect to empty address."); | |
return; | |
} | |
if(address.slice(0,5)!="ws://"&&address.slice(0,6)!="wss://")address="ws://"+address; | |
if(conn){ | |
conn.close(); | |
log("","Reconnecting..."); | |
} else { | |
log("","Connecting to '"+address+"'..."); | |
} | |
conn=new WebSocket(address); | |
conn.addEventListener("open",function(){ | |
log("","Connected."); | |
}); | |
conn.addEventListener("message",function(msg){ | |
log(">",msg.data); | |
}); | |
conn.addEventListener("close",function(ev){ | |
log("","Connection closed with code "+ev.code+(ev.reason?", reason '"+ev.reason+"'":"")); | |
}); | |
conn.onerror=function(ev){ | |
log("","Websocket error: "+ev.message); | |
}; | |
} | |
function sendMessage(s){ | |
log("<",s); | |
conn.send(s); | |
} | |
function closeConnection(){ | |
if(!conn){ | |
log("","Connection already closed."); | |
return; | |
} | |
log("","Closing connection..."); | |
conn.close(); | |
conn=null; | |
} | |
var numthemes=3,themeidx=0; | |
function cycleTheme(){ | |
document.body.classList.remove("theme"+themeidx); | |
themeidx=(themeidx+1)%numthemes; | |
document.body.classList.add("theme"+themeidx); | |
if(localStorage){ | |
localStorage.setItem("theme",themeidx); | |
} | |
} | |
document.addEventListener("keydown",function(ev){ | |
switch(ev.keyCode){ | |
case 82: //r | |
if(ev.altKey){ | |
reconnect(); | |
ev.preventDefault(); | |
return false; | |
} | |
break; | |
case 84: //t | |
if(ev.altKey){ | |
cycleTheme(); | |
ev.preventDefault(); | |
return false; | |
} | |
break; | |
case 190: //. | |
if(ev.metaKey||ev.ctrlKey){ | |
closeConnection(); | |
ev.preventDefault(); | |
return false; | |
} | |
break; | |
} | |
}); | |
window.addEventListener("load",function(){ | |
if(localStorage&&localStorage.getItem("theme")){ | |
themeidx=+localStorage.getItem("theme"); | |
document.body.classList.add("theme"+themeidx); | |
} | |
log("","Type an address to connect."); | |
var wsinput=document.getElementById("wsinput"); | |
wsinput.focus(); | |
wsinput.addEventListener("keypress",function(ev){ | |
if(ev.keyCode==13){ | |
if(conn)sendMessage(ev.target.value); | |
else { | |
address=ev.target.value; | |
reconnect(); | |
} | |
droppedCurrent=null; | |
historyidx=null; | |
if(ev.target.value!=inputhistory[inputhistory.length-1])inputhistory.push(ev.target.value); | |
ev.target.value=""; | |
} | |
}); | |
wsinput.addEventListener("keydown",function(ev){ | |
if(ev.keyCode==38){ //up | |
if(historyidx==0||inputhistory.length==0)return; | |
if(droppedCurrent==null){ | |
droppedCurrent=ev.target.value; | |
historyidx=inputhistory.length-1; | |
} else { | |
historyidx--; | |
} | |
ev.target.value=inputhistory[historyidx]; | |
} | |
if(ev.keyCode==40){ //down | |
if(droppedCurrent==null)return; | |
historyidx++; | |
if(historyidx==inputhistory.length){ | |
ev.target.value=droppedCurrent; | |
droppedCurrent=null; | |
} else { | |
ev.target.value=inputhistory[historyidx]; | |
} | |
} | |
}); | |
}); | |
window.addEventListener("beforeunload",function(ev){ | |
var msg="You still have a connection open." | |
if(conn){ | |
(ev||window.event).returnValue=msg; | |
return msg; | |
} | |
}); | |
</script> | |
<style> | |
html{ | |
height:100%; | |
} | |
body{ | |
height:calc(100% - 20px); | |
margin:8px; | |
} | |
body{ | |
font-family:Monaco,"Menlo Sans","Courier New",Courier; | |
font-size:14px; | |
} | |
body.theme0{ | |
background-color:#112; | |
color:#b8b8b8; | |
} | |
body.theme1{ | |
background-color:#000; | |
color:#bbe; | |
} | |
body.theme2{ | |
background-color:#fff; | |
color:#000; | |
} | |
code{ | |
background-color:rgba(128,128,128,0.3); | |
border:1px rgba(96,96,96,0.3) solid; | |
border-radius:4px; | |
} | |
div#wscontainer{ | |
height:calc(100% - 200px); | |
/*border:1px rgba(128,128,128,0.6) solid;*/ | |
} | |
div#wslogcontainer{ | |
height:calc(100% - 20px); | |
overflow-y:scroll; | |
} | |
table#wslogtable{ | |
width:100%; | |
} | |
tbody#wslog{ | |
width:100%; | |
} | |
tbody#wslog > tr{ | |
width:100%; | |
} | |
tbody#wslog > tr > td:first-child{ | |
width:15px; | |
} | |
tbody#wslog > tr:nth-child(2n){ | |
background-color:#181828; | |
} | |
input#wsinput{ | |
background-color:#445; | |
border-width:0; | |
height:17px; | |
width:calc(100% - 4px); | |
margin-left:2px; | |
color:#b8b8b8; | |
} | |
/*input#wsinput:focus{outline:none;}*/ | |
footer{ | |
margin-top:80px; | |
font-size:11px; | |
} | |
</style> | |
</head> | |
<body class="theme0"> | |
<div style="float:right"> | |
<!--<span><code>alt-t</code>: switch theme</span>--> | |
<span><code>alt-r</code>: reconnect</span><br> | |
<span><code>cmd/ctrl-.</code>: disconnect</span> | |
</div> | |
<h1>wscat</h1> | |
<div id="wscontainer"> | |
<div id="wslogcontainer"><table id="wslogtable"><tbody id="wslog"></tbody></table></div> | |
<input type="text" id="wsinput"> | |
</div> | |
<footer>© 2015 Tom Smeding</footer> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment