Can't get sockets working - what silly thing am I missing? - php

I am trying to get into the brave new world of web sockets, but I can't get anything working.
I have downloaded and tried several PHP socket servers, but no joy. They seem very scarce on step-by-step info on what to do to actually get the thing working on your own server.
I am passing the path to the server script as the first argument to new WebSocket() - e.g. 'ws://localhost:33/sockets/server.php'. Is that right?
Should I be passing anything as the second param? I've read up, but I'm not quite sure.
Any help appreciated.

Path that you are passing to WebSockets have nothing to do with actual Path within filesystem.
When WebSocket is connecting to server, it just uses actual address "localhost" in your case, and port "33". Then in HTTP request on handshaking it will take the "path" details which is "/sockets/server.php" in your case, and will put them in handshake, so first line of handshake will look like that:
GET /sockets/server.php HTTP/1.1
So it will be used by you application to decide what to do with it. If you want to use it and make it look like related to actual files or use it your own way.
Here is some info from RFC 6455 on WebSockets URIs.
As well do not use port 33, as it is might be taken by dsp service. Check ports map here.
If you Bind your server side WebSocket to port 33, then it should proceed with connection.
After connection of TCP layer is established, it should proceed through HTTP Requests that is Handshaking.
After that is done, and was success. JavaScript on client side will throw onopen callback. If something went wrong it will throw onerror and onclose events.
After connection is successfully established and WebSocket did proceed through handshaking messaging can be made. Client will receive raw string as message, or binary (if server sends binary data, message with specific opcode). But server will receive data with framing and some header. Browsers do apply deframing automatically so on Client side you dont need to worry about that. But on Server side you have to do it or yourself, or use some existing libraries to handle that for you.
Here is official document of WebSockets protocol: RFC 6455. It has all information you need to know all aspects of WebSockets protocol.
In meantime, you might be interested for looking into ready solutions. And go through their examples.

Related

ActiveMQ - any way to disconnect another client based on the client ID?

I am using Amazon MQ which is a managed Active MQ instance. I am connecting over STOMP with PHP using this stomp-php library. I plan on having these listeners running continuously, and if disconnected, reconnect. My concern is that for some reason or another, a script will stop working but the client won't disconnect. If this happens, I wouldn't be able to reconnect with that client ID until the other client disconnects.
If this happens, I want to be able to close the connection remotely. I don't know if this is possible with STOMP though, I don't see anything about it in the STOMP documentation. It seems that once you connect through STOMP, you're connecting as a client and everything you do is in relation to that client.
I looked at the ActiveMQ documentation and I see in Artemis (IDK if AmazonMQ is Artemis or Classic) there's a closeConnectionWithClientID JMSServerControl method. This seems like it's exactly what I want to do, but through STOMP or some other way via PHP.
Does anyone know how I would go about achieving this?
AmazonMQ is based on ActiveMQ "classic" 5.x versions. Via the STOMP client there isn't a way to forcibly disconnect another client, there isn't a way through any of the client protocols as that'd be a horrendous security and usability issue.
To remove a client you need to use the JMX management APIs in 5.x which I'm nut sure are exposed in AmazonMQ instances but that'd be the place to start looking. In 5.x the JMX API can be exposed using Jolokia such that an HTTP request could be used to invoke them once you has established authentication and authorization to the admin role you hopefully have configured.

Google Talk over XMPP

I am trying to establish a XMPP connection to talk.google.com on port 5222, however I am getting a 301 MOVED PERMANENTLY response redirecting me to hangouts.google.com.
I know Google abandoned GTalk, and what I could find is really inconclusive of whether the service is actually still up and running (although not maintained), or not.
I almost gave up thinking it is just not there anymore, however last try using external client (Adium...like Pidgin but for Mac) instead of my own library (XMPP-PHP), ended up actually connecting to the server and sending messages all fine.
Is there something I'm missing?
You want to do an DNS SRV record lookup to find the actual server to connect to, eg https://kingant.net/check_xmpp_dns/?h=gmail.com says that the client records for gmail.com's XMPP server are xmpp.l.google.com and alt{1..4}.xmpp.l.google.com
Alternatively, you could use a hangups-based solution to speak the native Hangouts protobuf format: https://github.com/tdryer/hangups/
I have found the right URL to be talk.l.google.com.

How to listen what SoapClient sends to server during request?

I'm trying to debug a PHP script that sends request to server via SOAP. I have to insert a structured variable into SOAP request message but I'm getting errors with rather unhelpful fault messages like "string" :/
So I'd like to check the raw request sent by SoapClient class to server. By "raw" I meant I need XML string being passed. Like
<soapenv:Envelope ...>...<myVar>...</myVar>...</soapenv:Envelope>.
How do I do that? I run the script on Debian host so I tried looking at netcat but I cannot find something suitable among the options list.
There are multiple ways to achieve this, I think the "rawest" one would be to trace/view the network traffic with a tool like Wireshark.
Please take a look at https://www.wireshark.org/docs/wsug_html_chunked/AppToolstcpdump.html where is described how to trace the network traffic on a linux system and store it into a file which you can open with wireshark and analize the network traffic.
If I've remembered it correctly, this only works flawless if you have an unsecured connection between the two hosts.
Edit
If you are only interested in the requests XML the php SOAP client has a method "__getLastRequest" http://php.net/manual/en/soapclient.getlastrequest.php

Using proxy with sockets in PHP

I have some PHP code in which XML data is being passed between server and client using sockets. socket_create( AF_INET, SOCK_STREAM, SOL_TCP ), socket_read(), socket_write() are the functions being used to pass XML and not HTTP requests.
Now if I want to use a proxy for client to use to connect through to the server, how can I do that in PHP?
I am new to sockets and from what I have gathered, there exists this library https://github.com/clue/php-socks which I don't fully understand right now but the idea is to setup the middleman using the same library which is essentially the proxy in this case. How would I go about using a SOCKS4/5 proxy obtained from https://www.socks-proxy.net/ or paid ones? Is the above mentioned library the only option? Feels like PHP should have something built in already.
Please advice.
This should be a comment, but it's a bit long.
Feels like PHP should have something built in already
I'm struggling to imagine why it should. PHP is a language designed for serverside web development. Proxies are a client side technology. Having said that the curl extension has comprehensive support for HTTP proxies.
There is no single proxy protocol. Certainly SOCKS and HTTP are the most visible protocols for proxies but there are lots more. Was there a specific reason for choosing SOCKS?
If it were me I would just setup transparent port forwarding using iptables (Linux) or a socat instance or haproxy (Unix, MSWindows).

PHP Socket Server (for Android Push Notifications) - Security / Authentication Issue

I have recently written a socket server in PHP that will be handling communication between an Android phone application and my PHP webserver. Due to the fact that Android doesn't natively support push style notifications we are going to be using our webserver as the middleware layer to handle our 'pushes'.
The socket server is stable, runs well, and seems to scale nicely. While I would eventually like to re-write this in C I don't have the skill necessary to do that right now so I am going to be staying in PHP for at least a short while. As of this moment our Android emulator is able to communicate through the server, get pushes, etc. so that part is all covered.
My concern is that, right now, anyone can open a socket to my server and will be given a client connection. While we won't be passing sensitive data back and forth I don't want to allow just anyone to connect over and receive broadcast information, eat up my resources, and clog my server in general.
The question is, how do I secure a server like this? Let's assume that I am running on port 25,000--can I set up some sort of SSL layer on that port and expect devices like the Android to be able to communicate over that port without any special protocols or jumping through hoops?
I have considered asking the connecting clients to authenticate their user against our user database before being given a client connection, but that would require the passing of credentials in plain text over the network which I am NOT about to do.
Any suggestions on this would be very helpful--I am rather new to straight TCP communication from PHP and feel like I might just be missing something simple that allows for authentication on this level.
Additional information: If I am able to get a valid username and password securely I would be using MySQL to validate the user and then accept/reject their connection based on the results of the query.
Thanks in advance..
First, I hope you've implemented your PHP socket server in a fashion that allows more than one client to be connected at the same time. This is not as trivial as it should be given the absence of threads in PHP, but it's certainly.
Now, if you already have a socket server implemented, adding TLS support is easy. Just run stunnel and have your PHP socket server only accept requests on the local interface.
I don't think SSL is really going to solve your problem. At best with SSL you can provide each client with a client certificate and do client certificate validation on the server. But you'll need to manage tons of certificates then. Or give everyone the same client certificate (not a good idea).
You'll have to authenticate the client using his credentials. You are right that you don't want to send the credentials in plain text over the network, but there are simple alternatives. Take a look at e.g. HTTP Digest Authentication (http://en.wikipedia.org/wiki/Digest_access_authentication) or xAuth (http://dev.twitter.com/pages/xauth). You don't have to implement these techniques over HTTP; you can just as well send a challenge (a realm) over a simple tcp socket after you have accepted the connection. The client should then send a valid response within a short timeframe or the server aborts the connection.
By the way, did you consider HTTP streaming? See http://ajaxpatterns.org/HTTP_Streaming
It would probably make your life a lot easier as you can rely upon some other service (e.g. Apache) doing the hard work for you, and you can focus on the business value of your application.
you might want to consider:
Cloud to Device Messaging : http://code.google.com/android/c2dm/index.html
The only drawback is that it is only supported by android >=2.2
Not sure why you guys didn't use some off the shelf messaging library/server for java, then create an android service that connects to the message broker and handles all initial authentication.
The service would simply sit there and wait for any incoming messages.
(I'm pretty sure that listening for network data doesn't power up the radio, only when the data is actually there that the radio powers up. I suspect this is how C2DM works.)
This is better then polling because you're only waiting for data. You're not constantly sending packets requesting data. But you knew that already.
I did this, (I used the rabbitmq-java library and the rabbitmq message queue server) and had push style notification for my app in no-time. Even with Android 1.5 devices.
About security:
You could also implement your own security but without having to send plain-text passwords. Simply encrypt the passwords using something like MD5 before passing it through the network.
Then compare the encrypted password with the encrypted password you have on file.
This way, only encrypted passwords will go through the network.

Categories