WebSocket??

Started by bottomleypotts, April 19, 2017, 01:31:47 PM

Previous topic - Next topic

bottomleypotts

Has anyone had a go at WebSockets? Would it even be possible??

I'd like to interact with something like this:
http://websocket.org/echo.html

Thanks in advance, BP

JTaylor

I think there is a good example in the Tech Database.   I have a WebService Server I wrote so not the back-n-forth interaction like a chat room but still "listens" and responds.


Jim

JTaylor

Guess I should clarify that it uses the WinSock extender.  So not exactly the same thing maybe.

Jim

stanl

They have examples for both JavaScript and .NET - which WB can work with. You might want to detail what you would like to accomplish and maybe some of their jscript code and we can help with how it might be adapted to WB

bottomleypotts

Thanks for the replys guys.

I was wanting some help interacting with a websocket service - ie. open connection to web server (via ws://echo.websocket.org), and send and receive information over the open connection. All interactions with the 'net in winbatch I can find are with HTTP(s) sessions involving GET/POST ie. open, send request, wait, receive response, connection is closed.

The url I posted is a websocket echo server that I would do some testing on - I would like to send a message and have it received back. Looking at their code, it appears event driven and I can't see how this would translate back to winbatch. It would be nice to have simple code like their, rather than to have to write winsock code.

JTaylor

Quote from: bottomleypotts on April 20, 2017, 05:05:41 AM
It would be nice to have simple code like their, rather than to have to write winsock code.

Have you looked at the example in the Winsock Help file under sAccept()?   It is about the same length as the sample code you referenced above and, I think, does pretty much what you are asking.   Can't see how it is less "simple" than the other.

Jim

td

We still haven't quite figured out the "MiracleHappens()" function yet.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

bottomleypotts

Have had a look at Winsock. If I was able to write the code in winsock to talk with websocket services then I wouldn't be using winbatch to code.

Have a look at http://www.codemag.com/article/1210051. I guess I'm not getting my requirement across, but it's not a simple TCP/UDP socket, it's a protocol akin to HTTP/HTTPS/IMAP/IMAPS/POP/POPS. I'm not inclined to write code to interact with HTTP/HTTPS servers. So obviously an extender does not currently exist to communicate with WS/WSS services, I was wondering if anyone had successfully used a COM object, similar to how WinHttp.WinHttpRequest.5.1 is used to interact with websites (well that's how I do it anyway) rather than use the wwint44i extender.

I'm not sure what the miraclehappens() remark is about, but it used to occur in extenders and I just had to worry about writing my apps because the big protocols were taken care of by the dedicated programmers at Wilson who aimed to solve our problems.

JTaylor

Sorry.  Thought you were wanting to set up both parts of the conversation.   As Stan said, expand on what you want to accomplish.    I assume you know you could use a browser control in WinBatch and interact with the Service via a WebPage but have it embedded in WinBatch?

Jim

td

Quote from: bottomleypotts on April 21, 2017, 07:21:49 AM
Have had a look at Winsock. If I was able to write the code in winsock to talk with websocket services then I wouldn't be using winbatch to code.

Have a look at http://www.codemag.com/article/1210051. I guess I'm not getting my requirement across, but it's not a simple TCP/UDP socket, it's a protocol akin to HTTP/HTTPS/IMAP/IMAPS/POP/POPS. I'm not inclined to write code to interact with HTTP/HTTPS servers. So obviously an extender does not currently exist to communicate with WS/WSS services, I was wondering if anyone had successfully used a COM object, similar to how WinHttp.WinHttpRequest.5.1 is used to interact with websites (well that's how I do it anyway) rather than use the wwint44i extender.

I'm not sure what the miraclehappens() remark is about, but it used to occur in extenders and I just had to worry about writing my apps because the big protocols were taken care of by the dedicated programmers at Wilson who aimed to solve our problems.

With a few minor exceptions, extenders require more than a little knowledge of the protocols and/or Windows subsystem of interest.   To the best of my knowledge no extender offers a solution to an undefined problem.

Generally, the first step to developing a solution is spec'ing out the requirements.   The tools follow.  WinBatch has several ways to implement web or socket based services.  There is the previously mentioned WinSock extender, there are the Windows built-in COM based HTTP and XML objects, and WinBatch CLR hosting (.Net) with all of its built-in and third-party classes.   The Tech Database has a few examples for all of these approaches but I doubt you will find a cut-and-paste solution there.   But you do have this forum with willing members that can give you insights when you get stumped.       
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

JTaylor

Here is something to get you started perhaps.   The problem with using something like WinHttp, if it could be done which I am not sure it could, is that you would not have access to the events.  This marries Winbatch with HTML & Javascript.  It assumes you are using a recent version of WinBatch.  Also, didn't do anything with Secure connection.

Jim

Code (winbatch) Select


WinHide("")
Home_Path = DirScript()
Data_Path = ShortCutDir("Local AppData",0,@TRUE):"wb_rad\"
WebSocket_Ini = Data_Path:"WebSocket.ini"
DirChange(Home_Path)
GoSub Load_Routines
IntControl(49,3,0,0,0)

;Call(".\websocket.wdl","")
WebSocketFormat=`WWWDLGED,6.2`

WebSocketCaption=`WebSockets`
WebSocketX=-01
WebSocketY=-01
WebSocketWidth=364
WebSocketHeight=274
WebSocketNumControls=003
WebSocketProcedure=`WS`
WebSocketFont=`DEFAULT`
WebSocketTextColor=`DEFAULT`
WebSocketBackground=`DEFAULT,128|128|128`
WebSocketConfig=0

WebSocket001=`001,017,358,254,COMCONTROL,"co_Web_obrowser",DEFAULT,"Shell.Explorer.2",DEFAULT,170,DEFAULT,DEFAULT,DEFAULT,"128|128|128"`
WebSocket002=`305,003,050,012,PUSHBUTTON,"pb_Web_Exit",DEFAULT,"E&xit",6,930,DEFAULT,DEFAULT,DEFAULT,DEFAULT`
WebSocket003=`007,003,050,012,PUSHBUTTON,"pb_Web_SendMessages",DEFAULT,"Send &Messages",1,930,DEFAULT,DEFAULT,DEFAULT,DEFAULT`

ButtonPushed=Dialog("WebSocket")


Exit

:Load_Routines




#DefineSubRoutine WS(Web_Handle,DMsg,DCID,DEInfo,ChangeInfo)

Switch (DMsg)
    Case @deInit
    DialogProcOptions(Web_Handle, @deTimer,1000)                          ; TimerEvent (0- Off).
    DialogProcOptions(Web_Handle, @deClose,1)                             ; Close selected (IntControl(49....) (1-On, 0-Off).
    DialogProcOptions(Web_Handle, @dpoDisable,0)                          ; Dialog Disable (1-Disable, 2-Wait cursor, 0-Enable).
    DialogProcOptions(Web_Handle, @dpoBkground,-1)                        ; Change Dialog Background (Bitmap File or RGB String).
    DialogProcOptions(Web_Handle, @deEdText,1)                            ; EditBox or Multi-LineBox.
    DialogProcOptions(Web_Handle, @deCbCheck,1)                           ; CheckBox.
    DialogProcOptions(Web_Handle, @dePbPush,1)                            ; Pushbutton/PictureButton.

    FilePut(DirScript():"websocket.htm",ws_htm)
    ws_server  = "ws://echo.websocket.org"
    use_tls    = 0
    ws_msg     = "Hello"
    log_txt    = ""
    begin_it   = 0
       
    obrowser = DialogObject(Web_Handle,"co_Web_obrowser",@doGetObject)
    url = "file:///":StrReplace(DirScript():"websocket.htm","\","/")
    obrowser.navigate(url)

    Break
  Case @deTimer
    If begin_it == 0 Then
      obrowser.document.GetElementByID("ws_server").value = ws_server
      obrowser.document.GetElementByID("use_tls").value   = use_tls
      obrowser.document.GetElementByID("ws_msg").value    = ws_msg
      begin_it = 1
    EndIf
    DialogProcOptions(Web_Handle, @deTimer,0)
    Break
  Case @deClose
    ws_server = obrowser.document.getElementByID("ws_server").value;
    Display(1,"Current Server",ws_server);
    Return 9
    Break
  Case @dePbPush
    Switch(DialogProcOptions(Web_Handle,@dpoCtlNumber,DCID))
      Case DialogProcOptions(Web_Handle,@dpoCtlNumber,"pb_Web_SendMessages")
        msgs = "This is":@TAB:"all":@TAB:"of":@TAB:"my":@TAB:"messages"
        For x = 1 to ItemCount(msgs,@TAB)
          ws_msg = ItemExtract(x,msgs,@TAB)
          If ws_msg == "" Then Continue
          obrowser.document.GetElementByID("ws_msg").value = ws_msg
            Anchor = obrowser.document.getElementById("send_box")
            objEvent = obrowser.document.createEvent("HTMLEvents")
            If objEvent == "" Then
              Anchor.click
            Else
              objEvent.initEvent("click", @true, @true)
              Anchor.dispatchEvent(objEvent)
            EndIf
        Next
        Break
      Case DialogProcOptions(Web_Handle,@dpoCtlNumber,"pb_Web_Exit")
        ws_server = obrowser.document.getElementByID("ws_server").value;
        Display(1,"Current Server",ws_server);
        Return -1
        Break
    EndSwitch
  Break
EndSwitch
Return -2

#EndSubRoutine

;  RegSetDword(@REGCURRENT, "Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION[***YOUR_APP***]", 11001,32)

ws_htm = $"
<!DOCTYPE html>
<html>
  <head>
  <meta charset="utf-8" />
  <title>WebSocket Test</title>
  <script language="javascript" type="text/javascript">


  function testWebSocket(ws_server)
  {
    websocket.onopen = function(evt) { onOpen(evt) };
    websocket.onclose = function(evt) { onClose(evt) };
    websocket.onmessage = function(evt) { onMessage(evt) };
    websocket.onerror = function(evt) { onError(evt) };
  }

  function new_socket() {
    document.getElementById("output").innerHTML = "<br>Testing Connection...<br>";
    var ws_server = document.getElementById("ws_server").value;
    if (ws_server === "") { alert("Must provide server"); return; };
    websocket = new WebSocket(ws_server);
    testWebSocket(ws_server);
  }

  function close_socket() {
    if (websocket.readyState > 1 && websocket.readyState !== 'false') { alert("You are not connected."); return;};
    websocket.close();
  }

  function onOpen(evt)
  {
    if (websocket.readyState > 1) { alert("You are not connected."); return;};
    var ws_server = document.getElementById("ws_server").value;
    if (ws_server === "") { alert("Must provide server"); return; };
    writeToScreen("CONNECTED");
    doSend("WebSocket rocks");
  }

  function onClose(evt)
  {
    writeToScreen("DISCONNECTED");
  }

  function onMessage(evt)
  {
    writeToScreen('<span style="color:: blue;">RESPONSE:: ' + evt.data+'</span>');
  }

  function onError(evt)
  {
    writeToScreen('<span style="color:: red;">ERROR::</span> ' + evt.data);
  }

  function doSend(ws_msg)
  {
    if (websocket.readyState > 1) { alert("You are not connected."); return;};
    if (ws_msg === "") { ws_msg = document.getElementById("ws_msg").value; };
    if (ws_msg === "") { alert("Must provide Message"); return; };
    writeToScreen("SENT:: " + ws_msg);
    websocket.send(ws_msg);
  }

  function writeToScreen(message)
  {
    document.getElementById("output").innerHTML = document.getElementById("output").innerHTML+"<br>"+message;
  }

  function onClearLog() {
   document.getElementById("output").innerHTML = "";
  };

   var ws_server = "ws:://echo.websocket.org";
   websocket = new WebSocket(ws_server);
   testWebSocket(ws_server);

  </script>
<style>

input.button {
         width:: 100px;
{


</style>
  </head>
 
<body bgcolor="##808080">

<table border="1" width="100%%">
<tr>
<td>Server::</td>
<td width="495">
<input type="text" id="ws_server" value="ws:://echo.websocket.org" size="45" />&nbsp;<input type="checkbox" id="use_tls" name="use_tls" value="0" />
Secure?</td>
<td> <input type="button" class="button"  id="connect_box" onClick="new_socket()" value="Connect" name="Connect" /></td>
<td><input type="button" class="button" id="disconnect_box" onClick="close_socket()" value="Disconnect" name="Disconnect" /></td>
</tr>
<tr>
<td>Message::</td>
<td width="495"><input type="text" id="ws_msg" size="45" /></td>
<td><input type="button" class="button"  id="send_box" onClick="doSend('')" value="Send" name="Send" /></td>
<td><input type="button" class="button"  id="clearlog_box" onClick="onClearLog()" value="ClearLog" name="ClearLog" /></td>
</tr>
</table>

  <div id="output"><br> Testing...<br></div>
</body>
</html>
                         

$"

Return

bottomleypotts

Again, sorry folks. I thought I made myself clear in my objective: I'd like to interact with something like http://websocket.org/echo.html. If you need a more concrete example of where I might use websockets, think having my server interacting with Slack in real-time. As opposed to what I do at the moment, which is poll for new information - inefficient. But instead of going full hog, I thought interact with a simple echo service might be an easier request.

To the best of my knowledge extender offers a solution to an problem. WS/WSS is not a new problem. And it's not a trivial bottomleypotts one off problem either but an extension of an existing standard for interacting with a server. Hence the request for help and obvious inability to explain the MiracleHappens() function.

Thanks for the help Jim! I agree WinHttp is not the solution, not being functionally spec'd to handle websockets. Your suggestion is certainly creative. But I don't know how it would go about interacting with a service with real and sometimes overwhelming rtm requirements. At the moment Slack allows me to set up an events based connection, where it connects to me and sends the messages. I will proceed with this ;-)

JTaylor

Not sure what else to offer.   While my example requires some user interaction, which is what you requested, it also demonstrates how you might send and/or receive an unlimited number of messages with no user interaction at all and easily extract the data to do with as you wish. 

Jim

td

Quote from: bottomleypotts on April 21, 2017, 08:09:54 PM
To the best of my knowledge extender offers a solution to an problem. WS/WSS is not a new problem. And it's not a trivial bottomleypotts one off problem either but an extension of an existing standard for interacting with a server. Hence the request for help and obvious inability to explain the MiracleHappens() function.

Not sure what you are trying to say by "extender offers solution to an problem" but new "standards" happen and in many cases fade away all the time.  There is a new one in the In-box on a weekly if not daily basis.   It never has nor will it ever be the intention to have WinBatch chase after them - new or old.  That pursuit is inherently futile.  The intentions is that WinBatch provides the underlying core tools that allow users to pursue whatever derivative standards they choose.    In the case of "WebSockets", WinBatch offers several technologies that might be able to interact without polling, if you choose to use them.   If you had been lucky, you might have found an example in the Tech Database.  However, WebSocks are not something that appears to have drawn much interest from WinBatch users.   This is suggested by the fact that it is "not new" but no examples exist in the database or on this forum.   

As an example of a possible tool, there is some chance that you can use WinBatch's CLR hosting with Microsofts's .Net Foundation Class Library's WebSocket client and server  classes.  The one restricting factor is that it was not completely implemented until .Net 4.5 and not completely supported on all platforms. 

Any possible solution is going to require some planning, work and a climb up a learning curve.     
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade