Search Unity

  1. We are migrating the Unity Forums to Unity Discussions. On July 12, the Unity Forums will become read-only. On July 15, Unity Discussions will become read-only until July 18, when the new design and the migrated forum contents will go live. Read our full announcement for more information and let us know if you have any questions.

JavaScript -> WebService

Discussion in 'Scripting' started by zumwalt, Apr 25, 2007.

  1. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    I know how to do this with IE. No issues.
    I do not know how to do this for the other browsers. Has anyone had any success doing this with other browsers?

    Reason why I am asking, is that my client played in a web browser chatters with the webservice that I wrote in C#, this in turn chatters with my server (3 Tier model at the moment)

    So the webService component is my bridge to greener pastures for my game. Other than limiting my users to IE (which I can't do, because of my Mac base), how would I accomplish this?
     
  2. MatthewW

    MatthewW

    Joined:
    Nov 30, 2006
    Posts:
    1,356
    What all needs to be connected? If you need stuff inside a Unity app to talk to the web, you can just use the WWW class.

    If you have a web login system and the Unity application is an extension of that, then it gets a little more complicated--you'd have to pass in the currently logged-in user to Unity's content and vice versa.

    In the past I've done extremely elaborate game tracking with Flash projects. I've only done some simple stuff with Unity, so far, but all of the concepts are the same. I'm tracking simple game stats with the web version of I Hate Clowns:

    Code (csharp):
    1. Pies thrown: 93,358
    2. Levels played: 5,165
    3. Game beaten: 115 times
    That's all done via simple WWW calls. I can probably help if you can give a specific example of what you're doing...
     
  3. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    I have the unity web player passing information out to javascript functions, then these javascript functions currently call a physical web service wsdl (asmx) passing on the values to the web service along with the player can call functions from the web service and cause reactions from the server.

    This all works just fine from IE, but Firefox, Safari, other browsers don't react the same. So, what I need to do is have Javascript talk to possibly a Java Applet, then that Java Applet talk to a Java Servlet, since the entire premise of a web based application is a pull situaion where it requires the browser to talk to the servlet and get responses.

    So here I am, Not very good at Java Applets, let alone how to make javascript call a function in a java applet which in turn calls a java servlet.

    I don't think what I have working with javascrip and asp.net web service will work on safari and firefox, and my ISP refuses to install AJAX...
     
  4. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    Actually I was slightly fooled, apparently Unity overrides all javascript on page.
    This page:
    http://www.jbwws.com/unity/test.htm
    properly uses
    <body onload="init()">
    This then created my AI link.

    Same code, just pasted onto the Unity page where my game resides at:
    http://www.jbwws.com/unity/faith.html
    My onload is hijacked, and I can't execute my init() script.
    Now, if I take over the javascript by force, click on the Call Init button, this forces the Init() to run, then click on Call Method, you will see Axe appear and Unity will physically close its control.

    So I must be mistaken, hopefully someone can explain to me, how to I "share" javascript on the page with Unity?

    That single page shows that Unity completely overrides the javascript component of the page.
    *frowns*

    View and use in IE
     
  5. MatthewW

    MatthewW

    Joined:
    Nov 30, 2006
    Posts:
    1,356
    Why don't you just have Unity talk directly to a backend script without routing through on-page JavaScript? I'm missing something here...
     
  6. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    Maybe I am approaching this problem from the wrong angle then, Unity can (I thought) only talk to script directly on the page that the control exists on, not server side script.

    I have not been successful yet in placing a Unity control on an ASPX page and it have access to the C# functions associated with that page.

    I do not want to trigger a page postback and cause a page refresh. Everything that loads with the page needs to be focused and available to the Unity player.

    I have a shared class on the server which contains a hashtable of my players and there data, the other thing I have is a local set of variables that contains all player specific data which is populated upon successful player login.

    These are all server side events. The user only sees the resulting fields populated by this information. I guess this thing needs to be rounded back (since I was going stickly off the javascript interaction), to wether or not Unity web player can communicate directly with serverside methods.

    In a web based situation, all I am doing is passing values generated by Unity back to the server and I don't want to leave the current page.

    The only thing Unity seems to lack, is an onload event for the player that allows you to input an array list of WSDL pages.

    These pages would then expose methods to Unity for the game, making Unity a SOAP client.

    That would bypass the need for javascript injection.
    On top of that, I want Unity to be able to modify html fields on the page, like labels for instance, which you are doing in script, a Unity call of something like:

    page.label1.text="this value"

    Page = current page the player is on, label1 is a label on the page, and text is its value.

    Maybe I have way overcomplicated this issue. Its an issue for me right now. I need the client to talk to the server and prefferably through soap natively.
     
  7. MatthewW

    MatthewW

    Joined:
    Nov 30, 2006
    Posts:
    1,356
    Unity can talk directly to backend scripts, although only via GET requests (no POST support, and nothing above the HTTP application layer like web services technologies).

    That's more than enough to implement functionality, though. For instance, you could do something like the following:

    Code (csharp):
    1.  
    2. WWW loginRequest = new WWW(String.Format("login.aspx?user={0}&password={1}", WWW.EscapeURL(loginVariable), WWW.EscapeURL(passwordVariable));
    3.  
    The server-side script would be hit by the user's browser, exactly as if the user was visiting that page--for example http://yoursever/login.aspx?login=matthew&password=dancingponies

    In this example login.aspx would output data, probably either a value representing whether the login succeeded or a session ID for Unity to append to all future calls. In a real-world scenario you should pass in an MD5 hash or similar for the password and not the actual thing.

    Unity is entirely platform-agnostic with its WWW class. It isn't aware of the technology being used on the server (how would it?), and thus has no way to seamlessly interoperate with any scripts there.

    There are AJAX setups for various languages that do magic behind the scenes to set up bindings so that functions in server-side scripts can be called by name from the client. That's another option, but IMO it needlessly complicates thing. Also, what do you mean that your ISP can't "install" AJAX? You could create an AJAX script with completely static files with no server-side scripting. Granted, it wouldn't do much without dynamic output, but nothing special on the server enables the actual technology...

    Anyway, you should look at it this way: Unity can't access methods in server-side scripts, not directly. What it can do is visit URLs and fetch their output.

    If you have a huge amount of data to pull down, you'll need to serialize it in some form and then turn the serialized data back into a hashtable or whatever once it's in Unity. Depending on the complexity you could get away with simple CSV-style formatting for your output, or you could bump up to full XML formatting (although you should verify that the XML classes are available in a web player first).

    Hope this helps!
     
  8. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    AJAX install places several files into the server GAC, those files allow the web server to recognize the AJAX components and the website can utilize them. (I think there is 1 main DLL that does most of the work for the script to back end communication)

    URL's can only hold so much information in them. So at some point, the data would become truncated. This is where allowing the SOAP WSDL to be used in conjunction to the player would come in extremely handy.

    I'll break down my object calls and see what I can accomplish based on your suggestions, very much appreciated, hopefully I can respond late tonight with results.
     
  9. MatthewW

    MatthewW

    Joined:
    Nov 30, 2006
    Posts:
    1,356
    Bizarre on AJAX--the world of IIS is a scary place ;)

    Yeah, GET requests do have length limitations. It would be nice if OTEE implemented POST requests (which should be a very easy addition).
     
  10. hsparra

    hsparra

    Joined:
    Jul 12, 2005
    Posts:
    750
    Am I missing something? Why not use the .Net classes. That way you can do POST, SOAP, RPC, stream, whatever. Also, my understanding is SOAP is sort of a hog so it is only good for slow things, slow being relative here.
     
  11. freyr

    freyr

    Joined:
    Apr 7, 2005
    Posts:
    1,148
    Unity can execute javascript code in the embedding html page. To set a form value, you would do something like this:
    Code (csharp):
    1. Application.ExternalEval (" formName.field.value='this value' ");
    See http://unity3d.com/Documentation/Manual/Unity Web Player and browser communication.html for more info on browser/plugin communication.
    To communicate back to the web server, I would use the WWW class as suggested by others. Implementing SOAP is probably an overkill in most cases, so I would just do simple URL calls, passing parameters in the url and returning simple strings from the server.
     
  12. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    fryer, apparently you didn't try either URL to see my point.
    I have script that answers calls from the client, thats not the point.
    The point is, that the UNITY control overthrows the javascript control on the page.

    If it didn't none of this conversation would be needed.
    I have a page, look at the test.htm page, that page uses onload for the body, which on the unity page of faith, it terminates the onload and doesn't allow me to use it.

    I don't want to use the URL.
    posts can get captured, so thus hashing it before sending it on the url will keep the data safe, however, this makes the url long, and a url can only hold so much data depending on browsers.

    So its not a solution, a bandaid at best and definately not a solution.
    Soap isn't slow, I have a collaboration applicaiton that thousands of underwriters use daily to retrieve information from a server, and thousands of calls to databases using soap from hundreds of agencies.

    I have production proof of soaps speed.
    My problem with the unity player at the moment is that it overrides the page so that you can't utilize javascript without unities permission.

    Just compare the test to the faith, they have the same code.
    Test loads, then you can collect data using soap.
    Faith loads with a failure (same code, same place, onload doesn't use init like it should because of the unity plugin). To fix this, I made 2 buttons, first button runs the init, so you click it, then the service is instansiated, you click the second button and unity goes bye bye.

    I really hope someone is understanding this and how Unity is taking full control of the on page script.
     
  13. hsparra

    hsparra

    Joined:
    Jul 12, 2005
    Posts:
    750
    Should something visibly happen when I click on the buttons on either page? Nothing changes for me.

    Good to know about your SOAP experience.
     
  14. podperson

    podperson

    Joined:
    Jun 6, 2006
    Posts:
    1,371
    First -- I see no evidence that Unity breaks JavaScript on a web page. Are you sure?

    I can stick an onload event in my weasel demo page and it works just dandy.

    I'd suggest you do your debugging in FireFox with Web Developer extensions installed and watch the little stop sign indicating JavaScript errors. You probably have some error that's killing your JavaScript independent of Unity (and it may not be an error in JScript -- hence your code works in IE).

    Worst case, you can load the Unity player inside an iframe. If Unity is messing up JavaScript in the iframe, it can't touch the page outside it -- and if the page in the iframe is hosted in the same domain as the outer page, there's no sandbox, so you can talk to the containing page using JavaScript and vice versa.
     
  15. freyr

    freyr

    Joined:
    Apr 7, 2005
    Posts:
    1,148
    I didn't see your previous post. I was only reading the second one.
    As I'm not running on a PC, i can't test that web service functionality. All I get in Safari is "Value undefined (result of expression service.useService) is not object." from both pages. (So it does call init on both, at least in Safari.)
    What ExternalEvals are you running from the player? You are not redefining the init function from there by any chance?

    Web services also post urls behind the scenes so you are at best achieving security through obscurity.
     
  16. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    This has nothing to do with the body "onload" working, but rather body "onload" not working., this is because the code in the player is calling a method that uses the service which is null until it is initialized. Since it is not initialized, it is null and onload didn't trigger. So in both cases in safari, the onload didn't trigger.

    Since "ONLOAD" isn't working because of Unity taking control of the page script, I had to make a way to force the Init().

    In IE Only, what happens on the Faith page, is that you click on "Call Init" which forces the "init()" to execute, thenyou click on "call method" which calls the soap method, and then Unity closes. Its that simple.

    The Test.htm loads just fine in IE and if you click on "call method" it returns to you the word Axe.

    I am 100% positive that Unity takes control of the script on the page. Those two pages in unison show this as proof.

    SOAP transport layer does not take place on the URL.
    It hadn't dawned on me to use a floating IFrame, I'll give that try. That might give me the trick I need to get around this issue.

    The only browser that like this is IE, this is because I am using a webservice.utc file (Microsoft translation file written in Javascript for webservice use).

    I will be pulling an all nighter tonight when I get home from work, specifically focusing on all the different ways to make this work. One of the reasons why I went ahead and upgraded to Pro was because of the compiling for the PC so I could test this on Mac, PC and Browsers, using the webservice.utc isn't a solution for cross browser compatibility, but I wanted it as an option because of the SOAP interface.

    Time to get out the sledge hammer and chissle, there has to be a way for this to work on all browsers and I still utilize soap. I'll eventually figure out how. No way to give up on it now, to much code done to that end.
     
  17. MatthewW

    MatthewW

    Joined:
    Nov 30, 2006
    Posts:
    1,356
    Of course it does. Here's what the request to the server looks like:

    Code (csharp):
    1.  
    2. Hypertext Transfer Protocol
    3.     POST /unity/thinktank/AI.asmx HTTP/1.0\r\n
    4.     Accept: */*\r\n
    5.     Accept-Language: en-us\r\n
    6.     Referer: [url]http://www.jbwws.com/unity/test.htm\r\n[/url]
    7.     soapaction: "http://tempuri.org/UpdateInventory"\r\n
    8.     Content-Type: text/xml; charset="UTF-8"\r\n
    9.     User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; bgft; .NET CLR 2.0.50727; .NET CLR 1.1.4322)\r\n
    10.     Host: [url]www.jbwws.com\r\n[/url]
    11.     Content-Length: 805
    12.     Connection: Keep-Alive\r\n
    13.     Cache-Control: no-cache\r\n
    14.     \r\n
    15. eXtensible Markup Language
    16.     <?xml
    17.         version='1.0'
    18.         encoding='utf-8'
    19.         ?>
    20.     <SOAP-ENV:Envelope
    21.         xmlns=""
    22.         xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    23.         xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    24.         xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/"
    25.         xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
    26.         xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
    27.         xmlns:tns="http://tempuri.org/"
    28.         xmlns:s="http://www.w3.org/2001/XMLSchema"
    29.         xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
    30.         xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
    31.         xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    32.         xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
    33.         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    34.         <SOAP-ENV:Body>
    35.             <UpdateInventory
    36.                 xmlns="http://tempuri.org/">
    37.                 <inObj>
    38.                     Axe
    39.                     </inObj>
    40.                 </UpdateInventory>
    41.             </SOAP-ENV:Body>
    42.         </SOAP-ENV:Envelope>
    43.  
    And the response from the server:

    Code (csharp):
    1.  
    2. Hypertext Transfer Protocol
    3.     HTTP/1.1 200 OK\r\n
    4.     Connection: keep-alive\r\n
    5.     Date: Fri, 27 Apr 2007 17:40:36 GMT\r\n
    6.     Server: Microsoft-IIS/6.0\r\n
    7.     X-Powered-By: ASP.NET\r\n
    8.     MicrosoftOfficeWebServer: 5.0_Pub\r\n
    9.     X-AspNet-Version: 2.0.50727\r\n
    10.     Cache-Control: private, max-age=0\r\n
    11.     Content-Type: text/xml; charset=utf-8\r\n
    12.     Content-Length: 375
    13.     \r\n
    14. eXtensible Markup Language
    15.     <?xml
    16.         version="1.0"
    17.         encoding="utf-8"
    18.         ?>
    19.     <soap:Envelope
    20.         xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
    21.         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    22.         xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    23.         <soap:Body>
    24.             <UpdateInventoryResponse
    25.                 xmlns="http://tempuri.org/">
    26.                 <UpdateInventoryResult>
    27.                     Axe
    28.                     </UpdateInventoryResult>
    29.                 </UpdateInventoryResponse>
    30.             </soap:Body>
    31.         </soap:Envelope>
    32.  
    That's all SOAP really is...XML data back and forth. As mentioned, you could try C# implementations of SOAP, or worst case you could find of write one that uses sockets.

    In my honest opinion you should take a step back from Microsoft technologies like SOAP and do something less complicated and more direct with simple variable/response requests.
     
  18. shaun

    shaun

    Joined:
    Mar 23, 2007
    Posts:
    728
    @Matthew - agreed, I don't really see an advantage with using SOAP to talk with Unity (unless more acronyms sounds cooler). Ive written a simple web service in ASP.NET to send XML data back and forth between unity and it works perfectly - combine that with a binary upload/download class and you can send pretty much anything to and from the server (using a standalone .exe of course).

    Cheers
    Shaun
     
  19. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    I am still working through this, have updated my wish list SOAP thread with my findings so far. I have more testing to do when I get home from work. Made the DLL on my Windows box, hopefully Unity will like it, if it does, I might have a partial solution.
     
  20. podperson

    podperson

    Joined:
    Jun 6, 2006
    Posts:
    1,371
    I tried your two pages (test and faith) in FireFox 2.x with Web Dev extensions and guess what? You code fails due to JavaScript errors on both pages.

    You're just assuming other browsers work the way IE does. They don't. Everything, from the order in which events occur to how you refer to objects with an id, to when those objects are considered to exist in the course of a page load can vary from IE. Oddly enough, if you can get your code working on Safari or FireFox or Opera, it usually suddenly just works on all three.

    Here are the JavaScript error consoles from the test page (no Unity involved) in FF2 and Safari with debugging switched on.
     

    Attached Files:

  21. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    Again, The Service is not an object error is because the INIT() is not running on the onload event. I can't seem to find any other way to explain that. I really don't expect the Service to return anything on Mozilla, Firefox, Safari, or anything other than IE (I think I mentioned that early on). Service is a member of the webservice.dtc file. This is a javascript file that defines how to translate webservice pages.

    Ultimately, for my game, I have decided that 2 weeks on this subject is to much time to place into figuring out how to make the web player talk via web service to the system.

    I have a working dll that allows unity in both stand alone compiles. (Mac and PC), works without a problem talking to a database. The problem I have discovered, regardless of this bing a script issue or not (which it is clearly browser dependent, so not a solution for me, only works in IE), is that the security model that the web player is living in, is less than adaquate to even use the webservice library I do have working for the IMac and PC stand alone builds. Meaning that the stand alones apparently include and use the DLL, but the web client does not.

    Unless they have a way to 'merge' my dll into the unityweb file and allow me to use it, I am SOL for how I have this currently working.

    There is also the fact of deployment size. The unityweb file is 15 megs, the deployable build for stand alone for both imac and pc is 32 megs in size. Why? I don't know.

    So I have come to the general conclusion that the web based version of my game will go on hold for a few months until a few more iterations of unity is developed and distributed to see if any of this changes and see if they come up with a way to stream content internally without me having to write alot of code to do it myself, which right now I don't have the time for, and I know its not on any hot list for this year.

    The error is plain and simple. No other browser is able to use the dtc file, thus no other browsers javascript is able to instansiate the service component of my code. Onload doesn't trigger init() when ANY browser opens including IE, but if Unity is not loaded on the page, IE triggers OnLoad and init() triggers.

    I've been through those loops a few dozen times over the past few days. I appreciate your showing screen shots of the error in your browser, it just confirms what I already know. OnLoad is not loading init() and the browser doesn't know what service is until it is initialized, and right now, your browser can't initialize the service component.

    I'll be beating my self over the head for another 6 months if I stay on the path of trying to fix that, so moving on for now, I'll revisit that later when I have come up with a cross browser solution, maybe something in java vs javascript, no idea at this moment.

    However, I know how to write dll's now that work with unity, I know how to make stand alones work with a webservice, and I am storing results of triggered events on a web server in another country with less than a 100 milisecond delay for the round trip of the result.