Jump to content

DWilliams

Members
  • Posts

    144
  • Joined

  • Last visited

    Never

Everything posted by DWilliams

  1. I'm developing an application that consists of several parts. The main website is written in PHP, but there are also several WebSocket servers that the user might need to connect to. The servers are written in C# and have no direct communication with the web server other than via sharing the same database. Where should I start reading to come up with a way to have website logins also authenticate the user on the WebSocket servers? Since the WebSocket connections are all done in client-side JS, nothing it does can be trusted. For example, if I have a WebSocket chat server, I don't want the connecting users to have to re-login but I also don't want to rely on the JavaScript to, for example, say "Hey, my name is Fred". I'd rather have the web server somehow tell the chat server "Yep, he's logged in as Fred, all is good".
  2. Getting all users by a state or city is very easy. Assuming you have this data in a database then just query with " WHERE city='whatever' " or the same for state/country. Distance based calculations are a bit more complicated, though. First you'll need to get the latitude and longitude for each city. The Google Maps API could probably help you here. They have services where you can pass addresses in and get the latitude/longitude returned. Once you have that you can calculate the distance between two lat/long points with a bit of math. See http://www.movable-type.co.uk/scripts/latlong.html for details on how to do that (implementation is in JavaScript but it shouldn't be too hard to convert to PHP). Assuming you don't have thousands and thousands of users you could probably just loop through each user and calculate their distance from the city in question and kick them out of the result set if they are too far away
  3. I don't know if this works on every platform, but in my particular Linux distro I just had to uncomment "extension=pdo_mysql.so" in php.ini
  4. Sockets can operate in two different modes: 1) Blocking (default) 2) Non-blocking If in blocking mode, then yes, execution will stop until all the data is sent, and all your other clients will be left waiting. If in non-blocking mode, the function will send what it can then return. However, the OS does not keep the unsent data and slowly send it as it is able. This is something you have to manage yourself. socket_write returns the number of bytes successfully sent. If that is less than what you attempted to send, you need to store the excess bytes somewhere and try again later. Hmm, I'd previously been just calling socket_write and assuming magical network fairies took care of everything from that point on and carried my data from server to client. I'm a bit confused as to how TCP comes into effect here, though. I know that TCP is supposed to ensure that my packets arrive at their destination all intact and orderly, but if I send a chunk of data with socket_write over my TCP socket and it doesn't all get to the other side, isn't that contrary to TCP's guarantees or am I thinking about this on the wrong level? Given this knowledge, allow me to think out loud (and probably incorrectly) for how this should be done properly: I call socket_set_nonblock() on a user's socket as soon as they connect. Instead of having a send method that simply passes data on through socket_write, I should have it add data to a buffer. I should have some other code somewhere (where?) that routinely checks buffers and writes what it can, subtracting what went through until all data is sent. I don't know if I'm massively overthinking this of massively underthinking it I'm beginning to think all of this cannot be accomplished in a timely manner with only one thread?
  5. A "simple" multiplayer game server using php/web sockets as the server and JS as the client. My 10MB example was a bit on the large side, nothing that large will likely ever be sent by the server, but still, if the server is locked while sending data then it will become locked up more the more users are connected, especially if their connections are bad. Might you have a link to something that explains how to better engineer a server?
  6. First things first I'm terrible with JavaScript so I'm muddling through almost everything I do with it My basic goal here is that I need to "include" a list of JS files into my main file and pause execution of my main script until they're loaded. After some googling I've found jQuery's getScript() method. I tried to make a script loader function based on my (working) image preloader. Here's my code: function loadScripts(callback) { var scripts = new Array('cCell.js', 'cPlayer.js'); var loadedScripts = 0; var numScripts = scripts.length; for(var i = 0;i < numScripts;i++) { $.getScript(resPath + 'js/' + scripts[i], function() { if(++loadedScripts >= numScripts) callback(); }); } } resPath is defined outside that function but I have checked to verify the paths it creates is a valid path to my script. No matter what I try, the callback never seems to get called. At first I had resPath set to be a complete URL to my resource folder. I read somewhere that JS has security features to prevent executing code from a remote URL or something so I tried replacing it with both relative and absolute paths to no avail. What am I doing wrong?
  7. Say I have a server written in PHP (don't ask ). Let's say I have 10 users connected to my script and one of those users, for the sake of the example, needs 10MB of data sent to them. If I send that data via socket_write(), does my program execution stop (therefor locking up every other user) until the data has gone through, or is the actual task of sending data over the tubes passed on to some lower level OS function so my program can get on with its flow?
  8. Sure, here's the server code: http://pastebin.com/a1Mzt3pC Pretty much any simple websocket will work for it, here's the one I was using to test: http://code.google.com/p/phpwebsocket/source/browse/trunk/%20phpwebsocket/client.html I don't take credit for most of it, I mainly pieced it together from several outdated and/or half-working sources. My main contribution to it is the handshaking code. It has flaws obviously, the main being is that it isn't coded to properly respond to ping/pong/close packets but the framework is there and ready to be implemented. It's a good starting point for somebody wanting to implement a server, though. Also, for people not used to working with sockets in PHP take note that by default PHP has no support for listening sockets. In Linux/mac you'll need to recompile with --enable-sockets and under Windows you have to enable some module.
  9. So it turns out the solution was much simpler than it seemed. The browser expects "\r\n\r\n" at the end of the handshake. Works fine with that, I now have a working websocket server
  10. You don't grant permissions to PHP specifically, the webserver PHP is running under (most commonly Apache) is the process that needs to have write permissions to the upload folder. Apache is configurable to run as a specific user/group that changes based on the OS or distro so you'll need to look that up in the main httpd.conf file (assuming you're using Apache, if not refer to your webserver's documentation).
  11. In that specific example you could do $car = substr('car/red/blue/gun/hit', 0, 3); http://php.net/manual/en/function.substr.php
  12. I've implemented it with hybi-17 but it doesn't work. I don't see any differences in the handshake between what I implemented and the IETF paper for version 8. This is my handshake function: function dohandshake($user, $buffer) { server_log(1, 'Requesting handshake...'); // Determine which version of the WebSocket protocol the client is using if(preg_match("/Sec-WebSocket-Version: (.*)\r\n/ ", $buffer, $match)) $version = $match[1]; else return false; if($version == { // Extract header variables if(preg_match("/GET (.*) HTTP/" ,$buffer,$match)){ $r=$match[1]; } if(preg_match("/Host: (.*)\r\n/" ,$buffer,$match)){ $h=$match[1]; } if(preg_match("/Sec-WebSocket-Origin: (.*)\r\n/",$buffer,$match)){ $o=$match[1]; } if(preg_match("/Sec-WebSocket-Key: (.*)\r\n/",$buffer,$match)){ $k = $match[1]; } // Generate our Socket-Accept key based on the IETF specifications $accept_key = $k . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'; $accept_key = sha1($accept_key, true); $accept_key = base64_encode($accept_key); $upgrade = "HTTP/1.1 101 Switching Protocols\r\n" . "Upgrade: websocket\r\n" . "Connection: Upgrade\r\n" . "Sec-WebSocket-Accept: $accept_key"; socket_write($user->socket, $upgrade, strlen($upgrade)); $user->handshake = true; return true; } else { server_log("Client is trying to use an unsupported WebSocket protocol ({$version})"); return false; } } I can't tell for sure whether it's working but I suspect the handshake is not working.The JS client connects to it but when it tries to send data, I get a "Error: INVALID_STATE_ERR: DOM Exception 11" exception, and the readyState never changes from 0. When I feed the sample keys into my function it produces the correct accept key...
  13. After some more tinkering I think I have confirmed that it is indeed the server script that's causing the problem. I don't see anything wrong with it but with new server code I was able to capture the packet. Now my problem is that the WebSocket protocol seems to be adapting so rapidly that trying to apply it seems like trying to hit a moving target. This is the packet I captured (sent from Chrome): GET / HTTP/1.1 Upgrade: websocket Connection: Upgrade Host: 192.168.1.29:12345 Sec-WebSocket-Origin: http://192.168.1.29 Sec-WebSocket-Key: 0fEMxyrlgsuDp8IA02nxCA== Sec-WebSocket-Version: 8 That differs from all the examples I can find on the internet as well as the Wikipedia page, so I guess I have to hunt down the IETF protocol description for version 8 and implement it off that...
  14. Hmm I tried setting up the websocket example from this page and it doesn't work either. Similar result. No connection is made although the server script still shows something hitting it. No handshake packets are sent on this example either. Maybe something else is the issue here? I'm not running through a proxy or anything. I've tried it both from the local machine as well as from another computer and the result is the same EDIT: I've also tried in both Firefox 8 and Chrome 15
  15. Yeah, the script outputs that it's being connected to: New client connected 0 Client disconnected 0 And I'm capturing loopback with wireshark. I can see all the packets for downloading the page itself, just nothing about websockets or the HTTP upgrade packet. I've looked through every HTTP packet it produces and run searches for any of the terms that should be in the handshake packet
  16. The server code is just some generic PHP socket server script I picked up for testing purposes: <?php // Set time limit to indefinite execution set_time_limit (0); function server_log($msg) { echo '[' . date('G:i:s') . "] $msg\n"; } // Set the ip and port we will listen on $address = 'localhost'; $port = 10000; $max_clients = 10; // Array that will hold client information $client = Array(); // Create a TCP Stream socket $sock = socket_create(AF_INET, SOCK_STREAM, 0); // Bind the socket to an address/port socket_bind($sock, $address, $port) or die('Could not bind to address'); server_log("Server started on {$address}:{$port}"); // Start listening for connections socket_listen($sock); // Loop continuously while (true) { // Setup clients listen socket for reading $read[0] = $sock; for ($i = 0; $i < $max_clients; $i++) { if (isset($client[$i]['sock'])) $read[$i + 1] = $client[$i]['sock']; } // Set up a blocking call to socket_select() if (socket_select($read, $write = NULL, $except = NULL, $tv_sec = 5) < 1) continue; /* if a new connection is being made add it to the client array */ if (in_array($sock, $read)) { for ($i = 0; $i < $max_clients; $i++) { if (empty($client[$i]['sock'])) { $client[$i]['sock'] = socket_accept($sock); echo "New client connected $i\r\n"; break; } elseif ($i == $max_clients - 1) echo "Too many clients...\r\n"; } } // end if in_array // If a client is trying to write - handle it now for ($i = 0; $i < $max_clients; $i++) { // for each client if (isset($client[$i]['sock'])) { if (in_array($client[$i]['sock'], $read)) { $input = socket_read($client[$i]['sock'], 1024); if ($input == null) { echo "Client disconnecting $i\r\n"; // Zero length string meaning disconnected unset($client[$i]); } else { echo "New input received $i\r\n"; // send it to the other clients for ($j = 0; $j < $max_clients; $j++) { if (isset($client[$j]['sock']) && $j != $i) { echo "Writing '$input' to client $j\r\n"; socket_write($client[$j]['sock'], $input, strlen($input)); } } if ($input == 'exit') { // requested disconnect socket_close($client[$i]['sock']); } } } else { echo "Client disconnected $i\r\n"; // Close the socket socket_close($client[$i]['sock']); unset($client[$i]); } } } } // end while // Close the master sockets socket_close($sock); That seems like it should work for purposes of getting the JS websocket to send its handshake
  17. I've been tinkering with websockets lately and attempting to create a server in PHP. I read this summary on Wikipedia to gain an understanding of the protocol. It seems rather easy to implement, but I'm having some issues. I have a test page with JavaScript attempting to open a websocket and a socket server script in PHP that does nothing other than listen for and accept connections. Now, this seems to work on the surface. A socket is opened and immediately closes, which is what I would expect since the server is not coded to follow websocket protocol. What is confusing me, however, is that no handshake request is ever sent by the JS client. I have wireshark set up and capturing all packets going back and forth, and the initial handshake packet described by Wikipedia is never sent. Maybe my sleep deprived brain is missing something obvious here, but shouldn't the client always send the first handshake packet as soon as the socket is opened, regardless of whether the server in question is just a dumb script that doesn't know what to do with it?
  18. I see what you're saying but luckily in my case, the script that does the inserting is executed by cron and not by visitors. In that case, it should be fine, right? The script will only run every 30 minutes or so. The script in question is connecting to a third party API and processing all new entries that have been added since the last script execution. Each remote entry has an ID, so I store IDs that have already been processed to ensure that they don't get processed again. Ideally my script will keep parsing new entries until it hits one with an ID equal to the most recently inserted ID in my database.
  19. ...to be the latest entry? If I want to get the ID of the last inserted row, can I just order by the PK and limit 1? I know about mysql_insert_id() and similar functions, but I need to do this from a separate script execution and those must be run directly after the insert.
  20. That seems like a hack-ish way of doing it but I can't find any other way to do it so it looks like that's what I'm doing to do, thanks
  21. Hmm I've been playing around with this and I think I'm almost to a solution. I figured out how to make imagemagick output to stdout, and I found the passthru() function which is designed for binary data like the images I'm dealing with. If I do something like this (using CodeIgniter), I get my image rendered correctly: $this->output->set_content_type('image/png'); passthru($imagemagick_command); passthru() doesn't have an option to return output, so that's not going to work in my case. Going back to exec, it can return output but it automatically separates lines and returns each line as an element in an array. I figure I can just implode the array to get it back as one contiguous file and store it in the database, but I cannot seem to display it again. My exec/recombine line looks like this: exec($magick_command, $output); $output = implode("\n", $output); The binary data is being stored in the database, but when I pull it out of the DB and try to send it to the browser (after setting my MIME type in the header, of course), it just gets output as a huge string of random characters (binary data being interpreted as text). What am I doing wrong?
  22. Basically, I want to have my script call Imagemagick montage to combine multiple images and store the result image as a blob in the database. Imagemagick, as far as I can see, just wants input images and an output image. Is there any way I can somehow manipulate my exec (or similar) function to store the result in a variable instead of somewhere on the filesystem?
  23. There's about 3 or 4 different forums I could post this in, but I guess I'll pick this one. Long story short I have an AJAX call that returns some code to be eval'd. In this case, it needs to update the report container div on my page with the results of the AJAX call. I'm not very experienced with JavaScript but this should be a simple enough task. When I set my AJAX function up to return document.getElementById('reportarea').innerHTML = 'test'; Then it works just fine. If I replace "test" with my report's HTML, nothing happens (presumably JS is erroring out on it). Now, I just figured this was a case of not escaping quotes or something, but I ran my report HTML through addslashes() and the same thing happens. The HTML the AJAX function returns is unpredictable and can contain all sorts of wonky stuff like linebreaks, semicolons, quotes, brackets, and whatever else. Currently this is a sample of what it's trying to return that does not work: document.getElementById('reportarea').innerHTML = '<b>Client:</b>CLIENTNAME<br /> <b>Date Range:</b> <br /><br /> <table border=\"0\" cellpadding=\"4\" cellspacing=\"0\"> <tr> <th>Listed</th><th>Acct #</th><th>Name</th></tr> <tr> <td>11/16/2009</td><td>AE1000</td><td>JOHN DOE</td><td>1600.00</td></tr> <tr> <td>11/16/2009</td><td>AE1000</td><td>JOHN DOE</td><td>1600.00</td><td>11/16/2009</td><td>AE 1001</td><td>JANE DOE</td><td>700.00</td></tr> </table> <br /><br /> <b>Number of Accounts:</b> 2<br /> <b>Total Placement Amount:</b> 2300<br /><br /> <b>NOTE: Interest, if assigned, will accrue on the above account(s). <br /> Thank you for choosing OURCOMPANY for your collection needs!</b> '; What do I actually need to do to prepare this HTML to be acceptable to JavaScript?
  24. Aha that explains it! I assume I can just change my header to something like this: <link type="text/css" href="http://example.com/myfolder/application/assets/css/redmond/jquery-ui-1.8.9.custom.css" rel="Stylesheet" /> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js"></script> <script>jQuery.noConflict();</script> And then change $ to jQuery everywhere I try to use it? That header is common to almost all of my pages, the jQuery stuff is pieced together from other sources and dumped into the page (mostly pieces of forms retrieved with AJAX).
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.