Page 1 of 1

web services

Posted: Fri Sep 07, 2018 7:58 am
by John
Does the latest BR! code have any access to the methods of web services ( )?

Are there any examples or documentation on the process?

Re: web services

Posted: Fri Sep 07, 2018 9:38 am
by gordon
The most popular underlying protocol for supporting Web Service communication is HTTP. Please note we are not speaking of HTML.

HTTP is a stateless (each transaction stands on its own) protocol for managing the transfer of data. Typically the protocol that underlies HTTP is TCP. TCP handles the reliability and user identification aspects of Internet transmission. And HTTP handles the transactions, by setting standards for controlling things like message length, buffer and cache management, and security considerations. TCP thinks one block at a time. HTTP thinks one transaction at a time. A transaction consists of an inquiry and, optionally, a response.

Web Services can use HTTP for managing it's transactions, which unlike HTML, do not imply the involvement of a human being. Web Services can handle machine to machine communication. There are several protocols that perform various functions for Web Services. However Simple Open Access Protocol (SOAP) is the most significant data formatting protocol in that environment. A description of SOAP can be found here:

As technology moves toward support for the Internet of Things (IOT) I can envision the day when a generic Home Controller will communicate with plug and play devices such as lamps or garage door openers using SOAP and the other Web Service protocols.

The BR Web Server supports the most recent HTTP protocol which is level 1.1. This includes a concept called chunking which breaks longer messages into chunks for applications such as large web pages, query responses, or file transfer. It also supports data encryption using SLL with certificates. Actually the SSL (secure) form of HTTP (called HHTPS) is mandatory with the BR Web Server. It is optional as to whether or not an application needs to support user login sessions. But HTTPS is a BR Web Server requirement with or without login support.

Laying on top of HTTP are the protocols for supporting web pages (HTML) and Web Services (XML, SOAP, WSDL, and UDDI). For web pages the text formatting protocol of choice is Javascript Object Notation (JSON). JSON is to HTML support as SOAP is to Web Services.

The IOT industry is in its infancy right now and it remains to be seen whether JSON will replace XML as the protocol underlying SOAP. I suspect it will one day because JSON is about as efficient and flexible as any text formatting protocol can get. Note that both JSON and XML are limited to text and are not useful for formatting lots of binary data values. Binary values can be converted to text using character sets such as UTF-8 but that is an inefficient way to manage the transfer of binary data.

Right now SOAP uses XML and HTML mainly uses JSON. Both use HTTP and HTTP uses TCP.

The BR Web Server supports all of this focusing mainly on the HTTP protocol. It also provides a convenient way to parse and compose JSON.

Re: web services

Posted: Fri Sep 07, 2018 1:13 pm
by John
So - is this a "Yes" I can access external web services methods? That's great! Are there any examples? Do I need "BR Web Server" to access web services? Is this a feature of BR! or a seperate product or just a really good example? Is there any documentation for it? How do I find out more?

Re: web services

Posted: Fri Sep 07, 2018 1:30 pm
by Gabriel
Here's an example of a function I wrote that checks the price of the passed in Crypto Coin, as of the given Date, by calling a web service hosted by the website CryptoCompare.

Code: Select all

    def library fnGetPrice(;CurrencyType$,AsOfDate,AsOfTime$,Exchange$,___,Connection,AsOfDate$,P,Market$)
       if ~len(CurrencyType$) then let CurrencyType$="BTC" ! BTC
       let fnLibraryLinkage

       if AsOfDate then
          if len(trim$(Exchange$)) then
             let Market$="&markets="&Exchange$
          end if

          open #(Connection:=fnGetFileNumber): "name="&CurrencyType$&"&tsyms=USD&ts="&str$(fnEpochTime(AsOfDate,AsOfTime$))&Market$&"&extraParams=SageLive, http=client",display,outin
          if len(trim$(Exchange$)) then
             let Market$="&e="&Exchange$
          end if

          open #(Connection:=fnGetFileNumber): "name="&CurrencyType$&"&tsyms=USD"&Market$&"&extraParams=SageLive, http=client",display,outin
       end if

       linput #Connection: String$ eof Ignore

       let String$(1:pos(String$,"USD")+4)=""
       let String$=srep$(String$,"}","")
       let fnGetPrice=val(String$) conv Ignore
       close #Connection:

Re: web services

Posted: Fri Sep 07, 2018 3:54 pm
by GomezL
This looked nifty, I decided to assign Line #'s and give it a try.

Fnepochtime is probably simple, but I didn't try to figure it out.

PRINT "Bitcoin Price:";Fngetprice("BTC",0,Time$,"")

You can remove line 60, see how quickly it returns a value, but the program loops and returns a value for 20 seconds.

It looks like the price changes roughly every 30 seconds or so (Might depend on the market).

The Connection Looks like this:
* ... s=SageLive

Code: Select all

00010   PRINT Newpage
00020   DIM String$*999,Market$*999
00030   LIBRARY "": Fngetprice

00040 for _Price=1 to 20
00050    PRINT "Bitcoin Price:"&date$("MM/DD/CCYY")&"-"&time$;Fngetprice("BTC",0,Time$,"")
00060 SLEEP(1)
00070 next _price

00099   STOP

00100   DEF LIBRARY Fngetprice(;Currencytype$,Asofdate,Asoftime$,Exchange$,___,Connection,Asofdate$,P,Market$)
00110     IF ~Len(Currencytype$) THEN LET Currencytype$="BTC" ! BTC
00120 ! let fnLibraryLinkage
00130     IF Asofdate THEN
00140       IF Len(Trim$(Exchange$)) THEN
00150         LET Market$="&markets="&Exchange$
00160       END IF
00170       OPEN #(Connection:=Fngetfilenumber): "name="&Currencytype$&"&tsyms=USD&ts="&Str$(Fnepochtime(Asofdate,Asoftime$))&Market$&"&extraParams=SageLive, http=client",DISPLAY,OUTIN
00180     ELSE
00190       IF Len(Trim$(Exchange$)) THEN
00200         LET Market$="&e="&Exchange$
00210       END IF
00220       OPEN #(Connection:=Fngetfilenumber): "name="&Currencytype$&"&tsyms=USD"&Market$&"&extraParams=SageLive, http=client",DISPLAY,OUTIN
00230     END IF
00240     LINPUT #Connection: String$ EOF Ignore
00250     LET String$(1:Pos(String$,"USD")+4)=""
00260     LET String$=Srep$(String$,"}","")
00270     LET Fngetprice=Val(String$) CONV Ignore
00280     CLOSE #Connection:
00290   FNEND

01000   DEF Fngetfilenumber
01010     LET _Next_File=1000
01020     DO While File(_Next_File-=1)<>-1
01030     LOOP
01040     LET Fngetfilenumber=_Next_File
01050   FNEND

02000   DEF Fnepochtime(Et_Date,Et_Time$)
02010     LET Fnepochtime=0
02020   FNEND

Re: web services

Posted: Fri Sep 07, 2018 4:12 pm
by Gabriel
My bad. fnEpochTime formats a BR Time and date into the format that the website uses, which I believe is number of seconds past jan 1, 1970 or something like that.

Hard coding it to 0 will, as you discovered, cause the website to always just return the current price. Here's the function if you want to be able to look up the price as of a given time in history.

But my main goal with the post was to show how easy it is to talk to any web page from BR using http=client. And how it doesn't depend on anything, and its built into BR, to answer your other questions.


PS. I bet the price changes a lot more frequently then every 1 second. I bet its updated many times per second. But I don't know -- did you find that its once per second with your testing?

Code: Select all

    dim T$(1)
    def library fnEpochTime(JulianDate;tTime$,___,H,M,S,EP,pm,epochStart,EpochDays,Epoch)
       if len(trim$(TTime$)) then
          if pos(lwrc$(TTime$),"pm") then
             let PM=1
          end if
          let TTime$=srep$(lwrc$(tTime$),"pm","")
          let TTime$=srep$(lwrc$(tTime$),"am","")
          str2mat(TTime$,mat T$,":")
          let H=val(T$(1)) conv Ignore
          let M=val(T$(2)) conv Ignore
          if udim(t$)>2 then
             let S=val(T$(3)) conv Ignore
          end if
          if PM then let H+=12
          let EP=(((H*60)+M)*60)+S
          let EP=12*60*60 ! 12 hours into the day seems average if no time is given.
       end if

       let EpochStart=Days("01/01/1970","mm/dd/ccyy")
       let EpochDays=JulianDate-EpochStart
       let Epoch=EpochDays*60*60*24
       let fnEpochTime=Epoch+EP

Re: web services

Posted: Mon Sep 10, 2018 6:59 am
by John
This is really helpful! When I try to run the sample code I get an error 4340 and syserr$ returns "Problem with the SSL CA cert (path? access rights?)". Am I forgetting something basic? Would I need to install an SSL certificate on my machine to use it?

Re: web services

Posted: Mon Sep 10, 2018 4:52 pm
by gordon
In this case your intent is to access web services. This can be done with HTTP client.

My earlier posting was concerning the provision of web services. For that you would need to use the BR Web Server.

You can do both in a single application but the 2 are not the same and they don't overlap in any meaningful way. Remember.. an HTTP transaction consists of an inquiry and a response. The Client initiates the Inquiry, and the server provides the response.

For HTTP Client, you will need a CA bundle named ca-bundle.crt located in the BR executable directory. This is a batch of top level root certificates from authorized certificate providers. The procedure for obtaining such bundles is described next.

CA Bundle Periodic Updating
From time to time CA root certificates expire just like end-user certificates. So it can be necessary to update your CA bundle as follows:

Download the current root certificate bundle from
It will be named cacert.pem. Rename it to ca-bundle.crt which is what BR will look for.

Re: web services

Posted: Mon Sep 10, 2018 5:01 pm
by Gabriel
Thanks Gordon! I was just about to reply but you beat me to it. You also gave a more thorough answer because I didn't know the cert expires after a while and I didn't know where to download a new one. I was just gonna share mine on here.


Re: web services

Posted: Tue Sep 11, 2018 10:02 am
by John
oh yes - now it works! Thank you, Gordon! Thank you, Luis! And Thank you, Gabriel!