creating a socket to connect to existing servers

Got a LiveCode personal license? Are you a beginner, hobbyist or educator that's new to LiveCode? This forum is the place to go for help getting started. Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller

Mark
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 5150
Joined: Thu Feb 23, 2006 9:24 pm
Contact:

Re: creating a socket to connect to existing servers

Post by Mark » Mon Dec 06, 2010 12:01 pm

Alex,

I think you started from an example again. I'm not entirely sure that you now actually know how sockets work. Do you realise that you don't close the socket after reading from it? I don't know what you want to do after reading from the socket, so I don't know whether keeping it open will cause problems.

You seem to be writing garbage to the socket. Look at the protocol to determine the correct data to be written to the socket.

Mark
The biggest LiveCode group on Facebook: https://www.facebook.com/groups/livecode.developers
The book "Programming LiveCode for the Real Beginner"! Get it here! http://tinyurl.com/book-livecode

maverickalex
Posts: 108
Joined: Sun Mar 15, 2009 11:51 pm

Re: creating a socket to connect to existing servers

Post by maverickalex » Mon Dec 06, 2010 1:02 pm

using Putty (as in the previous graphic) if i type "data" this means i can receive the raw data.
The example i used was the "get" command to retrieve the result of sim/multiplay/callsign.

hence this line.

Code: Select all

put "data" & return & "data" & return & "get sim/multiplay/callsign" & return into mess
You are correct about using an example to try to figure my way through this.

If i explain how i see the meaning of the code perhaps that will point to where my knowledge lets me down?

the socket is opened here.

Code: Select all

on startconnection
  open socket to "127.0.0.1:5501" with message connected
end startconnection
i'm sending the required protocol information here to retrieve my callsign information

Code: Select all

on connected theSocket
  put "data" & return & "data" & return & "get sim/multiplay/callsign" & return into mess
  write mess to Socket theSocket until crlf
   read from socket theSocket until return with message "callsignResult"
end connected
the info returned from the server and put into a field " callsign" here

Code: Select all

on callsignResult theSocket theMessage
   put theMessage into field "callsign"
end callsignResult
I know this is incorrect.

I understand that the socket needs to remain open until closed by the user as information from the server should be constantly read (or at least every minute or so)

Cheers
Alex

maverickalex
Posts: 108
Joined: Sun Mar 15, 2009 11:51 pm

Re: creating a socket to connect to existing servers

Post by maverickalex » Tue Dec 07, 2010 12:54 pm

still really struggling to get this to work in Rev.

i d/l a socket client from here.

http://revolution.byu.edu/internet/socketClient.rev

it connects to the socket but i dont understand why it won't receive info when i type the commands requested. such as data.help or get.
This should be so simple, but its maddening!

Mark
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 5150
Joined: Thu Feb 23, 2006 9:24 pm
Contact:

Re: creating a socket to connect to existing servers

Post by Mark » Tue Dec 07, 2010 5:37 pm

Alex,

I think that you need to make sure that you have configured your FG server correctly and that you send the correct commands to the server. Modify your script to close the socket after you have retrieved the information. Later on you can keep the socket alive.

Your Putty example doesn't help, because Putty is already connected to the server at this point and only needs to exchange commands. One of the commands is "data" and another command is "get". You can't do this when you talk directly to the server through a socket. Instead, you need to stick to the protocol, which you need to study.

Once the server is set up correctly and you send the right command, your script will get you either a confirmation from the server or an error messages. Note that an error message is a good result too, as it means that the server at least listened and tried to execute your commands.

Mark
The biggest LiveCode group on Facebook: https://www.facebook.com/groups/livecode.developers
The book "Programming LiveCode for the Real Beginner"! Get it here! http://tinyurl.com/book-livecode

maverickalex
Posts: 108
Joined: Sun Mar 15, 2009 11:51 pm

Re: creating a socket to connect to existing servers

Post by maverickalex » Tue Dec 07, 2010 6:52 pm

Thanks Mark,

I'm pretty sure the FGserver is configured correctly and outputing as it should.
It must be me not understanding the protocol correctly and how to implement it.

I'll go back to the drawing board again :?

Thanks for yuor patience

Mark
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 5150
Joined: Thu Feb 23, 2006 9:24 pm
Contact:

Re: creating a socket to connect to existing servers

Post by Mark » Tue Dec 07, 2010 7:16 pm

maverickalex ,

In that case, you shouldn't go back to the drawing board but instead study the protocol and make sure you send the correct data.

Mark
The biggest LiveCode group on Facebook: https://www.facebook.com/groups/livecode.developers
The book "Programming LiveCode for the Real Beginner"! Get it here! http://tinyurl.com/book-livecode

maverickalex
Posts: 108
Joined: Sun Mar 15, 2009 11:51 pm

Re: creating a socket to connect to existing servers

Post by maverickalex » Wed Dec 08, 2010 4:19 pm

ok i have re written the protocol and could see that previously the server was not sending any info as the protocol was incorrect.

i have now re written the file acars.xml which is the protocol and the server confirms that it will start on the port i have requested.

(from the command box of the FlightGear sim)

Code: Select all

Parse I/O channel request: telnet,socket,in,10,127.0.0.1,2222,tcp
  protocol = telnet
Setting I/O poll frequency to 10 Hz
Props server started on port 2222
Parse I/O channel request: generic,socket,out,1,127.0.0.1,2222,tcp,acars
  protocol = generic
Reading communication protocol from E:/newFGCVS/data/Protocol/acars.xml
  medium = socket
  direction = out
  hertz = 1
  hostname = 127.0.0.1
  port = 2222
  style = tcp
the new protocol looks like.

Code: Select all

<?xml version="1.0"?>
<PropertyList>
 <generic>

  <output>
   <binary_mode>false</binary_mode>
   <var_separator> </var_separator>
   <line_separator>\n</line_separator>
   <preamble>register FlightGear</preamble>

   <chunk>
    <type>string</type>
    <format>put</format>
   </chunk>

	<chunk>
	<name>callsign</name>
	<type>string</type>
	<node>/sim/multiplay/callsign</node>
	<format>callsign %s</format>
	</chunk>

   <chunk>
    <name>lat</name>
    <type>float</type>
    <node>/position/latitude-deg</node>
    <format>lat %f</format>
   </chunk>

   <chunk>
    <name>lon</name>
    <type>float</type>
    <node>/position/longitude-deg</node>
    <format>lon %f</format>
   </chunk>

   <chunk>
    <name>alt</name>
    <type>int</type>
    <node>/position/altitude-ft</node>
    <format>alt %d</format>
   </chunk>

   <chunk>
    <name>ground speed</name>
    <type>int</type>
    <node>/velocities/groundspeed-kt</node>
    <format>gnd %d</format>
   </chunk>

   <chunk>
    <name>heading</name>
    <type>int</type>
    <node>/orientation/heading-deg</node>
    <format>hdg %d</format>
    <factor>10</factor>
   </chunk>

   <chunk>
    <name>pitch</name>
    <type>int</type>
    <node>/orientation/pitch-deg</node>
    <format>pit %d</format>
   </chunk>

   <chunk>
    <name>bank</name>
    <type>int</type>
    <node>/orientation/roll-deg</node>
    <format>bnk %d</format>
   </chunk>

   <chunk>
    <name>mag variation</name>
    <type>int</type>
    <node>/environment/magnetic-variation-deg</node>
    <format>var %d</format>
   </chunk>

   <chunk>
    <name>comm frequency</name>
    <type>float</type>
    <node>/instrumentation/comm/frequencies/selected-mhz</node>
    <format>com %f</format>
    <factor>100</factor>
   </chunk>

   <chunk>
    <name>transponder frequency</name>
    <type>int</type>
    <node>/instrumentation/transponder/id-code</node>
    <format>xpd %d</format>
   </chunk>

   <chunk>
    <name>UTC hour</name>
    <type>int</type>
    <node>/sim/time/utc/hour</node>
    <format>hrs %d</format>
   </chunk>

   <chunk>
    <name>UTC min</name>
    <type>int</type>
    <node>/sim/time/utc/minute</node>
    <format>min %d</format>
   </chunk>

   <chunk>
    <name>comm transmit</name>
    <type>string</type>
    <node>/sim/multiplay/chat</node>
    <format>rtx {%s}</format>
   </chunk>

   <chunk>
    <name>direct comms transmit</name>
    <type>string</type>
    <node>/sim/squawkgear/transmit</node>
    <format>atx {%s}</format>
   </chunk>

<!--
/sim/messages/atc,pilot,ground,approach,ai-plane,mp-plane
/sim/multiplay/transmission-freq-hz (unused at present)
-->
 
  </output>

 </generic>
</PropertyList>
So now the issue of connecting my client app and reading the output packets.

looking at the protocol each packet should look like this.

callsign xxxx
lat xxxx
lon xxxx
alt xxxx

etc.

Now i just need to work out how to grab the data.

Code: Select all

onMouseUp
put "127.0.0.1:2222" into mySocket
open socket mySocket with message "connected"
endMousup

on connected
read from socket mySocket until crlf
end connected
i just need a basic start.

Progress? i don't quite know! my hair has progressed further to the back of my head i know that much!!

Mark
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 5150
Joined: Thu Feb 23, 2006 9:24 pm
Contact:

Re: creating a socket to connect to existing servers

Post by Mark » Wed Dec 08, 2010 5:34 pm

Hi maverickalex ,

That looks like progress indeed, at least with regarding to the server set-up.

As to your script, I think that your previous script was better. All it lacked was the correct data and a line to close the socket after reading data from it.

To build the correct data string, you need to start here. To find out what all that means, don't ask me but ask in the development forum. Those people know the protocol.

Once you know which data you need to send to the server, you can come back here to put it all together.

Good luck,

Mark
The biggest LiveCode group on Facebook: https://www.facebook.com/groups/livecode.developers
The book "Programming LiveCode for the Real Beginner"! Get it here! http://tinyurl.com/book-livecode

BvG
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 1239
Joined: Sat Apr 08, 2006 1:10 pm
Contact:

Re: creating a socket to connect to existing servers

Post by BvG » Thu Dec 09, 2010 3:21 pm

Sockets can be confusing because they need you to change your way of thinking a bit. So the easiest ay to learn is (unfortunately) to just do things by trial and error, until it 'clicks'.

In your example, you forget to use the automatically generated parameter (it's like a variable). I have used upper chars below to demonstrate what needs to be changed. As for reading stuff sent from a server, you'd need to do something similar to what is below (assuming a button). Note that it's completely untested!

Code: Select all

onMouseUp
  put "127.0.0.1:2222" into mySocket
  if mySocket is among the lines of the openSockets then --look up opensockets in the dictionary
    close socket mySocket
  else
    open socket mySocket with message "connected"
  end if
endMousup

on connected MYAUTOFILLED
  read from socket MYAUTOFILLED until crlf with message "readSomething"
end connected

--new stuff below here
on readSomething autoPort autoMessage
  put theMessage & return after field 1 --create a field first!
  read from socket autoPort until crlf with message "readSomething"
end readSomething
Various teststacks and stuff:
http://bjoernke.com

Chat with other RunRev developers:
chat.freenode.net:6666 #livecode

maverickalex
Posts: 108
Joined: Sun Mar 15, 2009 11:51 pm

Re: creating a socket to connect to existing servers

Post by maverickalex » Fri Dec 10, 2010 10:17 pm

well i succesfully worked out how to send data from the sim to a text file.

i used

--generic,file,out,1,(path to blank text file),acars

started the simulator and managed to get all the info from my protocol sent to the text file.

Code: Select all

callsign AVA001 lat 56.827568 lon 35.776875 alt 450 gnd 0 hdg 2540 pit 0 bnk 0 var 10 com 12050.000000 xpd 0 hrs 9 min 38
its a start!

Mark
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 5150
Joined: Thu Feb 23, 2006 9:24 pm
Contact:

Re: creating a socket to connect to existing servers

Post by Mark » Fri Dec 10, 2010 11:38 pm

maverickalex,

That look good, but that seems to be only the last part (Callsign|Data|) of the protocol. The firlst part (|Magic|Version|MsgId|MsgLen|ReplyAddress|ReplyPort|) seems to be missing.

Mark
The biggest LiveCode group on Facebook: https://www.facebook.com/groups/livecode.developers
The book "Programming LiveCode for the Real Beginner"! Get it here! http://tinyurl.com/book-livecode

maverickalex
Posts: 108
Joined: Sun Mar 15, 2009 11:51 pm

Re: creating a socket to connect to existing servers

Post by maverickalex » Sat Dec 11, 2010 5:54 am

actually all of that comes from the protocol file "acars"

Code: Select all

<?xml version="1.0"?>
<PropertyList>
 <generic>

  <output>
   <binary_mode>false</binary_mode>
   <var_separator> </var_separator>
   <line_separator>\n</line_separator>
   

	<chunk>
	<name>callsign</name>
	<type>string</type>
	<node>/sim/multiplay/callsign</node>
	<format>callsign %s</format>
	</chunk>

   <chunk>
    <name>lat</name>
    <type>float</type>
    <node>/position/latitude-deg</node>
    <format>lat %f</format>
   </chunk>

   <chunk>
    <name>lon</name>
    <type>float</type>
    <node>/position/longitude-deg</node>
    <format>lon %f</format>
   </chunk>

   <chunk>
    <name>alt</name>
    <type>int</type>
    <node>/position/altitude-ft</node>
    <format>alt %d</format>
   </chunk>

   <chunk>
    <name>ground speed</name>
    <type>int</type>
    <node>/velocities/groundspeed-kt</node>
    <format>gnd %d</format>
   </chunk>

   <chunk>
    <name>heading</name>
    <type>int</type>
    <node>/orientation/heading-deg</node>
    <format>hdg %d</format>
   </chunk>

   <chunk>
    <name>pitch</name>
    <type>int</type>
    <node>/orientation/pitch-deg</node>
    <format>pit %d</format>
   </chunk>

   <chunk>
    <name>bank</name>
    <type>int</type>
    <node>/orientation/roll-deg</node>
    <format>bnk %d</format>
   </chunk>

   <chunk>
    <name>mag variation</name>
    <type>int</type>
    <node>/environment/magnetic-variation-deg</node>
    <format>var %d</format>
   </chunk>

   <chunk>
    <name>comm frequency</name>
    <type>float</type>
    <node>/instrumentation/comm/frequencies/selected-mhz</node>
    <format>com %f</format>
   </chunk>

   <chunk>
    <name>transponder frequency</name>
    <type>int</type>
    <node>/instrumentation/transponder/id-code</node>
    <format>xpd %d</format>
   </chunk>

   <chunk>
    <name>UTC hour</name>
    <type>int</type>
    <node>/sim/time/utc/hour</node>
    <format>hrs %d</format>
   </chunk>

   <chunk>
    <name>UTC min</name>
    <type>int</type>
    <node>/sim/time/utc/minute</node>
    <format>min %d</format>
   </chunk>


<!--
/sim/messages/atc,pilot,ground,approach,ai-plane,mp-plane
/sim/multiplay/transmission-freq-hz (unused at present)
-->
 
  </output>

 </generic>
</PropertyList>
i didnt need to add anything like

(|Magic|Version|MsgId|MsgLen|ReplyAddress|ReplyPort|) anywhere as i beieve this is only added if you want other "online" multiplyers to receive the adat you are transmitting from your locol machine.

At this moment in time i only want the user to receive data about his own simulation statistics.

maverickalex
Posts: 108
Joined: Sun Mar 15, 2009 11:51 pm

Re: creating a socket to connect to existing servers

Post by maverickalex » Thu Dec 16, 2010 1:14 pm

So, i definitely found out i dont need to send any info. All i need to do is open a socket. keep that socket open. and read from it.

i need to start the app prior to the simulator and can send via tcp or udp.

I have tried all sorts of ways (as documented) (and failed) it would be nice to just know that my app could at least receive the data sent and display it in a field for now.

At least then i can work on seperating the info out.

maverickalex
Posts: 108
Joined: Sun Mar 15, 2009 11:51 pm

Re: creating a socket to connect to existing servers

Post by maverickalex » Sat Feb 26, 2011 9:20 am

I never did manage to get to read the info returned from the server. I have asked many people if i need to use anything else to read from the socket all say no, just connect and read.

I know i definitely connect using this script.

Code: Select all

on mouseUp
   if the label of me is "connect" then
      set the label of me to "disconnect"
      end if
   put field "ipfield" & ":" & field "portfield" & "|acars"into mysocket
   if mysocket is among the lines of the opensockets then
      close socket mysocket
   else
      open socket mysocket with message connected
      end if
end mouseUp

on connected mysocket
   read from socket mysocket until crlf with message "readpacket"
end connected

on readpacket autoPort autoMessage
  put theMessage & return after field "datafield" 
  read from socket autoPort until crlf with message "readpacket"
end readpacket
as in the command box for the simulator im using it tells me thats the server received a new connection.

i'm going to try a different route.

i can succesfully print to a text file the properties from my protocol file which grabs the info once per second and prints to a file.

This protocol file

Code: Select all

<output>
   <binary_mode>false</binary_mode>
   <var_separator>tab</var_separator>
   <line_separator>newline</line_separator>

   <chunk>
   <name>callsign</name>
   <type>string</type>
   <node>/sim/multiplay/callsign</node>
   <format>callsign %s</format>
   </chunk>

   <chunk>
    <name>lat</name>
    <type>float</type>
    <node>/position/latitude-deg</node>
    <format>lat %f</format>
   </chunk>

   <chunk>
    <name>lon</name>
    <type>float</type>
    <node>/position/longitude-deg</node>
    <format>lon %f</format>
   </chunk>

   <chunk>
    <name>alt</name>
    <type>int</type>
    <node>/position/altitude-ft</node>
    <format>alt %d</format>
   </chunk>

   <chunk>
    <name>ground speed</name>
    <type>int</type>
    <node>/velocities/groundspeed-kt</node>
    <format>gnd %d</format>
   </chunk>

   <chunk>
    <name>heading</name>
    <type>int</type>
    <node>/orientation/heading-deg</node>
    <format>hdg %d</format>
    <factor>10</factor>
   </chunk>

   <chunk>
    <name>UTC hour</name>
    <type>int</type>
    <node>/sim/time/utc/hour</node>
    <format>hrs %d</format>
   </chunk>

   <chunk>
    <name>UTC min</name>
    <type>int</type>
    <node>/sim/time/utc/minute</node>
    <format>min %d</format>
   </chunk>


  </output>

churns out the following

Code: Select all

callsign AVX001	lat 58.753239	lon -94.062309	alt 310	gnd 23	hdg 2500	hrs 18	min 30
callsign AVX001	lat 58.753178	lon -94.062637	alt 317	gnd 23	hdg 2500	hrs 18	min 30
callsign AVX001	lat 58.753120	lon -94.062958	alt 323	gnd 23	hdg 2500	hrs 18	min 30
callsign AVX001	lat 58.753063	lon -94.063286	alt 330	gnd 23	hdg 2500	hrs 18	min 30
callsign AVX001	lat 58.753006	lon -94.063599	alt 337	gnd 23	hdg 2500	hrs 18	min 30
callsign AVX001	lat 58.752945	lon -94.063927	alt 344	gnd 23	hdg 2500	hrs 18	min 30
callsign AVX001	lat 58.752888	lon -94.064255	alt 351	gnd 23	hdg 2500	hrs 18	min 30
callsign AVX001	lat 58.752831	lon -94.064583	alt 358	gnd 23	hdg 2500	hrs 18	min 30
callsign AVX001	lat 58.752769	lon -94.064911	alt 365	gnd 23	hdg 2500	hrs 18	min 31
callsign AVX001	lat 58.752712	lon -94.065239	alt 371	gnd 23	hdg 2500	hrs 18	min 31
what i would like to do is grab the data from the file ever 3 minutes and put each of the different items into its own field in my app.

so for example AVX001 would be in the callsign field, lat/lon in their respective fields and so on.
Once the flight is ended, i would then like to send the info to my database to be read.

Post Reply