Socket Rience

Getting into LiveCode for iOS? Ask your questions here.

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

rrBUSS9EE
Posts: 98
Joined: Wed May 02, 2012 3:46 pm

Socket Rience

Post by rrBUSS9EE » Tue Jul 03, 2012 12:45 am

Hi all…

Forgive the lack of brevity here… but the goal is to exchange data (or even synchronize it) between an OS X app and an iOS app over the network.

Not having any real experience with sockets, I broke down the Chat sample to separate server and client apps, which work between two desktops. I can transfer files and data snippets from one Mac to another over a wifi network, and it all works rather well.

Code: Select all

--HERE IS THE TEST CODE FOR THE SERVER
global clientSocket
on mouseUp
  -- provide visual feedback the server has been started
  disable me
  -- make it possible to stop the server
  enable button "Stop server"
  accept connections on port 1987 with message clientConnected
end mouseUp

on clientConnected s
   put s &CR before fld 1
   -- read in one line of data from the socket identified in the "s" variable
   read from socket s for 1 line
   -- remove any trailing return character
   put line 1 of it into tChatMessage
   put s into clientSocket
   put tChatMessage && "connected" & return after field "serverstatus"
   read from socket s until "scottyb" with message dataReceivedfromClient
end clientConnected

on dataReceivedfromClient s,data
   get the number of chars of data
   put it-6 into tstart
   delete char tstart to it of data
   --put "Client Data received"
   set the itemdel to tab
   if item 1 of data is "file" then
      put "received " & item 1 of data into whatwegot
      put whatwegot && "from" && s & CR before field "serverstatus"
      delete item 1 of data
      writethefile data
   else
      put  data & return before field "serverstatus"
   end if
   read from socket s until "RUSStyb" with message dataReceivedfromClient
   write "Data Received from"&&S&&"at"&&the time to socket clientSocket
end dataReceivedfromClient

on socketClosed s
   put s && "disconnected" & return before field "serverstatus"
end socketClosed

on writethefile data
   set the itemdel to slash
   put item 1 to -2 of the filename of this stack into thefolder
   put thefolder &"/myPict.jpeg" into thefile
   open file thefile for binary write
   write data to file thefile
   close file thefile
end writethefile

Code: Select all

--HERE IS THE CLIENT TEST CODE
local lCommSocket

on ClientConnect
   open socket field "host" & ":1987" with message "ClientConnected"
   set the label of button "connect" to "Disconnect"
end ClientConnect

on ClientDisconnect
   close socket lCommSocket
   set the label of button "connect" to "Connect"
end ClientDisconnect

on closeStack
  ClientDisconnect
end closeStack

on ClientConnected s
   set the label of button "connect" to "Disconnect"
   put s into lCommSocket
   write field "username" & return to socket lCommSocket
   read from socket s with message dataRecievedFromClient
end ClientConnected


on dataRecievedFromClient s,data
   put data & return before field "responses"
   -- specify that this message is to be sent again when more data is received
   read from socket s with message dataRecievedFromClient
end dataRecievedFromClient

on socketerror s,data
  set the label of button "connect" to "Connect"
  answer data
end socketerror

on sendData data
   set the itemdel to tab
   if item 1 of data is "file" then
      write data&"RUSSyb" to socket lCommSocket
   else write field "username" & ":" & data &"RUSSyb" to socket lCommSocket
end sendData

on ClientDisconnect
   close socket lCommSocket
   set the label of button "connect" to "Connect"
end ClientDisconnect
In taking the client code above and putting into an iOS app for testing, some of it works and some doesn't. I am able to open a socket to the server, and close it. But sending data is not working. Sometimes I see the send data flow in from a number of sends just after I close the socket, other times I get nothing and it seems like the server is waiting on something. I am obviously missing something with the iOS version of this code (below) so am hoping someone here has a bit of experience with rreSocket and can point it out to me.

Thanks!

Code: Select all

--iOS CLIENT TEST CODE
local lCommSocket 

on ClientConnect
   rreSocketOpen field "host" & ":1987", "ClientConnected"
   set the label of button "connect" to "Disconnect"
end ClientConnect

on ClientDisconnect
   rreSocketClose lCommSocket
   --  close socket lCommSocket
   set the label of button "connect" to "Connect"
end ClientDisconnect

on closeStack
  ClientDisconnect
end closeStack

on ClientConnected s
   set the label of button "connect" to "Disconnect"
   put s into lCommSocket
   rreSocketWrite lCommSocket, field "username" & return
   --   write field "username" & return to socket lCommSocket
   rreSocketRead s, , "dataRecievedFromClient"
   --   read from socket s with message dataRecievedFromClient
end ClientConnected


on dataRecievedFromClient s,data
   put data & return before field "responses"
   -- specify that this message is to be sent again when more data is received
   rreSocketRead s, , "dataRecievedFromClient"
   --read from socket s with message dataRecievedFromClient
end dataRecievedFromClient

on socketerror s,data
  set the label of button "connect" to "Connect"
  answer data
end socketerror

on sendData data
   rreSocketWrite lCommSocket, field "username" & ":" & data &"RUSSyb"
   --set the itemdel to tab
   --   if item 1 of data is "file" then
   --      write data&"RUSSyb" to socket lCommSocket
   --   else write field "username" & ":" & data &"RUSSyb" to socket lCommSocket
end sendData

sturgis
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 1685
Joined: Sat Feb 28, 2009 11:49 pm

Re: Socket Rience

Post by sturgis » Tue Jul 03, 2012 1:21 am

Is this a copy paste from your actual scripts? If so, your server seems to read until "RUSStyb"

your client on ios seems to send "RUSSyb" -- note the missing t.

I can't do IOS testing and don't see anything else yet from just looking at it, but let me know if this is part of the issue.

rrBUSS9EE
Posts: 98
Joined: Wed May 02, 2012 3:46 pm

Re: Socket Rience

Post by rrBUSS9EE » Tue Jul 03, 2012 1:58 am

Heh, heh… if it could only be a simple typo. No, my append string was a bit of an expletive so I thought I should edit it in the scripts I posted. :oops: I can assure you they match on this end.

But I removed ALL of the "until" portions of the socket reads just for testing and I'm still seeing the same behavior.


HELP! :?

sturgis
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 1685
Joined: Sat Feb 28, 2009 11:49 pm

Re: Socket Rience

Post by sturgis » Tue Jul 03, 2012 2:11 am

Unfortunately with it being on IOS, and using rresockets (neither of which I can test) i'm not sure how to help. Hopefully someone else will chime in.

rrBUSS9EE
Posts: 98
Joined: Wed May 02, 2012 3:46 pm

Re: Socket Rience

Post by rrBUSS9EE » Tue Jul 03, 2012 3:30 am

Nevertheless, my thanks.

rrBUSS9EE
Posts: 98
Joined: Wed May 02, 2012 3:46 pm

Re: Socket Rience

Post by rrBUSS9EE » Wed Jul 11, 2012 4:25 pm

Sorry to bump but still looking for some kind of example of sending data from iOS to OS X.

Is anyone doing this successfully?


thx

sturgis
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 1685
Joined: Sat Feb 28, 2009 11:49 pm

Re: Socket Rience

Post by sturgis » Wed Jul 11, 2012 5:34 pm

I still can't help with IOS but if you can stand to go without sockets on the IOS side you could possibly do something as mentioned in this thread.

http://forums.runrev.com/viewtopic.php?f=53&t=12377

Basically post data/custom url strings to server for processing, request changed data back from server to keep things in sync.

mwieder
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 3581
Joined: Mon Jan 22, 2007 7:36 am
Contact:

Re: Socket Rience

Post by mwieder » Wed Jul 11, 2012 6:00 pm

The rreSocket external on iOS is client-side only. You can't do the server-side stuff ("accept connections..."). As sturgis mentioned, you may be able to get by with setting up an http server on the OSX end, then posting data to the server from iOS.

On the bright side, it only gets worse on Android, where we don't have sockets at all. :shock:

gpb01
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 281
Joined: Sat Jun 04, 2011 5:41 pm

Re: Socket Rience

Post by gpb01 » Wed Jul 11, 2012 7:11 pm

Sorry rrBUSS9EE but which kind of data you have to to transfer ? Can you do data exchange through files or you need real-time ?

Because, if you don't need real-time and the data file exchange can be good for you, on ANY platform you can use the Dropbox REST API which use only HTTPS request ;)

Guglielmo

rrBUSS9EE
Posts: 98
Joined: Wed May 02, 2012 3:46 pm

Re: Socket Rience

Post by rrBUSS9EE » Wed Jul 11, 2012 7:25 pm

Hi Guglielmo,

In this case, it is a small binary file (an sqlite database). It would be nice in real time, but not necessary. It would be eminently do-able to transfer the entire file to the desktop, then synch the two databases there, and then replace the existing file on the iOS device.

Dumb question as I don't use dropbox, but wouldn't your solution require all users to establish a dropbox account?

mwieder
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 3581
Joined: Mon Jan 22, 2007 7:36 am
Contact:

Re: Socket Rience

Post by mwieder » Wed Jul 11, 2012 7:35 pm

You can set up a free Dropbox account here:
http://db.tt/UPFzt4L7

The answer to your question depends on what you're trying to do. If your end result is completely client-controlled (mobile and desktop) then yes, each client would have to set up a Dropbox account to use this solution. If you're doing something else then it's possible to upload the database to your Dropbox public folder, get a url for that file, and share it with any user with or without a Dropbox account.

For instance, you could post the sqlite database to your Dropbox public folder, get the url through an api call, and send the url to the desktop app to download.

rrBUSS9EE
Posts: 98
Joined: Wed May 02, 2012 3:46 pm

Re: Socket Rience

Post by rrBUSS9EE » Wed Jul 11, 2012 7:47 pm

The goal here is to have an exchange of data between an app on a user's iOS device and a sister app on their desktop… similar in fashion to what Bento does between Mac and iOS devices.

I think it would be inconvenient (and just a little bit kludgey IMHO) to require the user to signup for dropbox, and agree to having their data bounced up and down from the internet to utilize this feature. I would so much prefer direct communication over the wifi LAN like I have working from Mac-to-Mac.

But please keep the suggestions coming because right now I have nothing that works.

sturgis
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 1685
Joined: Sat Feb 28, 2009 11:49 pm

Re: Socket Rience

Post by sturgis » Wed Jul 11, 2012 10:05 pm

Do you need to be able to modify the database from both locations? Desktop and mobile? I assume the mobile will not ALWAYS be on the lan, and will be.. well... mobile.

How complex is the database? A single table? Multiple relational tables?

What I'm getting at is that it should be possible to setup a server on the desktop side (in LC of course), then when the mobile app starts up, a) check to see if its possible to hit the server (IE we're on the lan, the server is running) If so, post a request to the server to check for differences. Perhaps a table that tracks the last sync date and time, and any entries that are more recent than that sync date/time. If there are differences, post/and/or request them and make the 2 dbs match. Or if the db is small, just send the un-synced entries to the desktop db, close the db file and have the server send the updated db file back to the mobile device.

All this can be done with posts and gets from the mobile side. As for the server itself, I hate to keep touting Andres work but Rev on Rockets is a really great place to start learning. (Not sure what his terms of use are, but even if used just as a learning resource its pretty awesome) Basically rev on rockets gives you a ready go to single threaded http server. (with an easy to modify libcgi stack for adding your custom commands) I'd have to check and see how it handles post data just because i've never needed to post to it, but get works really well.

Also as mentioned in another thread, building your own server so that you can optimize it for your needs is a good option also, as long as you can set things up to receive post or get data. (which again, you might look at RoR to see how Andre does it)

rrBUSS9EE
Posts: 98
Joined: Wed May 02, 2012 3:46 pm

Re: Socket Rience

Post by rrBUSS9EE » Wed Jul 11, 2012 10:50 pm

Hello Sturgis,

It is acceptable, in fact desirable, to initiate the exchange only from the mobile app. It will not be on the LAN during its primary use. It is primarily a recording device, with only a basic feature set for browsing the data.

Within the scope of this project I would say the database is simple; several tables of simple text and numbers. But I want to leverage whatever we come up with for a larger project down the road that will have a much more complex scheme.

I'll have a look at ROR and see how it goes.

BTW... this seems like something most iOS developers would want/need to implement sooner or later, I am surprised no one has yet to invent this wheel. It would still be very desirable to discover why the whole socket thing isn't working here on iOS.

Thanks!

sturgis
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 1685
Joined: Sat Feb 28, 2009 11:49 pm

Re: Socket Rience

Post by sturgis » Wed Jul 11, 2012 11:36 pm

Actually I think most have invented this wheel in a different way, but similar to what we're discussing. Often people have a mySql database out on the internet with a php or livecode server script that will accept data and post it to the mysql database, and of course the reverse, a script that will query the online database for changes/updates. In fact if your mobile device is one with cell service you could just use the online mysql database directly with no local copy.

At some points sockets will officially arrive for IOS and android, and since you said that the mobile will be doing the initiating, (and not listening for connections) you could try rresockets again. Set up server with LC, connect to it from mobile and get them talking that way, but as mentioned I have pretty much zero way of testing on IOS so that method would be beyond me. And no rresockets for android so I can't test there either.

The sending of post data method though should work well enough since it sounds like you'll be dealing in transactions. Meaning mobile device initiates a connection with some type of command or query, server does what its supposed to and returns confirmation. And since you say the data acquisition will be done on the mobile device and that all the desktop has to do is receive data and sync it shouldn't be too difficult to accomplish.

As data is being acquired, set a database flag for each new entry. On sync, grab those flagged entries, post the data to the server, make sure you get confirmation, and unflag the entries.

Of course you could go the other mentioned direction and just post the whole file to your desktop server. This way you could set things up with versioning where you have multiple dated copies of the sqlite file. I'd avoid this method unless you are positive the file will remain relatively small. It would get old to have to send a huge file every sync.

Post Reply