 So my name is Jeff Kolasnikovic. I am the WebSocket guy. We're gonna talk about WebSockets for the next hour ish As you know it figures as soon as I get in the room my demo doesn't work I just want to test it. So there might not be a demo Anyway, I'm a brand new speaker and relatively new. I've been speaking for about a less than a year now and I encourage you all of you to get out there. All of you know something that Is useful and valuable I wanted to put this this is my favorite of those O'Reilly really Images ever Exactly The good thing about being a speaker is you don't have to pay $1,500 to Sit on Slack all day. You can do it for free I'm kidding Kind of So we're talking about real-time applications with PHP I want to get a few definitions out of the way. It'll make the rest of it a little clearer. I hope So Ever since the dawn of the internet, we've been looking to find a way to update the web browser with real-time information As web pages have increased in complexity. We've changed the approach we've used to getting new data on to the browser and Real-time is the goal like you want to be able to open a page and get real-time Stock quotes or games scores. I'm from Canada. So everything's hockey. There's no sports. There's only hockey Anyway real-time is the goal and we want to update the the web page with new information as soon as it's available Now how do we do that? Here's a here's another definition half versus full duplex half duplex means Communication can go one way at a time So the web browser can send information to the server or the server can send information to the browser But it doesn't work both ways full duplex means You can send it both ways the client can talk to the server the server can talk to the client And there's that open communication between the two So maybe I'm I'm dating myself But this is the old way we used to do it the browser would refresh every so often and we get new information on the page That's maybe not the best approach and actually One of the I mentioned sports earlier and one of the sports sites that I read Actually still does this. That's that's how they refresh the page and get new scores on it. It's absolutely embarrassing So this is the old way Ajax and this is half duplex So over time your browser says, hey, is there anything new? And the web server says Maybe well no not this time, but you know ask again in a minute and there's this process over and over again of the browser requesting new information from the server and The server responds Now there's a few problems with this approach One is every time you do a request it takes Some amount of time to establish the the connection get the data back process the data and Go from there Another problem is that we don't know who's actually connected to the server and That's really important for games because these could be different browsers Well, not this the response is going to come back to the same browser but that could be a different browser from that and If you have that doesn't scale this this approach doesn't scale all that well If you have a thousand browsers looking for information, that's a whole lot of polling a whole lot of startup time and a whole lot of Waiting This is Another approach Long polling so your browser goes and requests the web talks to the web server says is there anything new and Once there is new information the server sends the data back So this is actually what Facebook uses or it did a couple years ago They use that they use this approach because Web sockets weren't all that There wasn't web sockets to use really so This time here the web server The web server request is just holding on to that Request from the browser and doesn't send anything back until There is an update Once once they get a response from the server the client makes another request The good the upside with this is that you do know who's connected to the server at least for this part when the browser Does the request you know who's connected? But after here, you're not going to necessarily know who's connected. So this is the This is web sockets. So your browser makes a connection to the server And then once that connection is established They talk back and forth because you have you have a persisting connection the connections made you've authenticated it So you know who's connected There's also no startup time for a request. You've already formed the the connection so All the server or the browser has to do is make a is make a request or send some information and The other thing that's neat and this is full duplex by the way The other thing that's neat is either side can connect can terminate the connection So the server can say okay, we're done. We're done here and then the browsers Doesn't work anymore. So let's talk about web sockets. They're part of HTML 5 and They're The w3c's attempt at real-time communication for web browsers. Now. I'm sure this approach is going to change over time As as all technology does but this is this is the the new hotness right now The good news is it's this has been around since about 2008. I believe So it's been adopted by most of most web browsers The first time I gave this talk. There was a big red eight here under IE and That's a that's that's a whole fun ball game You have to you have to have a workaround for IE eight But you can see a small sliver here. This is web browsers by Market share, I believe so Well, IE eight is disappearing. It's still not gone. So where our web sockets used social media is An obvious one to me. It's easy to implement a chat with web sockets. You want real-time communication communication between people Something like Facebook Messenger would probably use it Updating your feed not necessarily that like I said before that's that's for They use long polling for that online games is an obvious one You want to update the screen as soon as somebody else makes a move Something like chess maybe not but you know a real-time game between two people Absolutely collaborating documents Trello uses web sockets to push Changes to collaborators if they if they both have the screen open and it does fall back to Ajax if you're using Internet Explorer 8 and Tracking live data so stuff like sports scores financial tickers that sort of thing So with PHP the implementation is is such that you need a web socket server And that's usually well that can be written in whatever you want, but in this case we're writing in PHP And you have your browser JavaScript now since web sockets are built into your browser You have access to it Was anybody else like a giant networking nerd and in university to your college? Like did you ever build like those those crappy servers that you just fire up and then you tell that into and like You felt like a big person because you just echoed it back and you're like I'm huge So that's this So that's this is a traditional socket in PHP So we're creating the socket. We're binding it to a port and an address and then we start listening and that's I Just wanted to show you how much Goes into building a web socket or sorry a traditional socket You can actually run this and I have a little more code that I'll share with you later and You can tell that to it and type some stuff and it echoes it out on the screen. It's it's awesome So yeah Web sockets are a little different. They're they're similar, but they're different So when you make a connection to a web socket, you're actually connecting to an endpoint. So slash chat and You you request slash chat and the web server sends back an upgrade a 426 upgrade and Then it sends Yeah, an upgrade Switching protocols and that opens the stream to the web socket server So you have a it's you have a web socket server and you have the HTTP server and They kind of work together here So really the main difference is the upgrade request for when you request slash chat Now since JavaScript has this Has web sockets built in Building something with node is pretty straight forward. We're not here to talk about node, but I Wanted to show you the six lines of code It takes to make a web socket server in in node and that's using Socket IO dot IO I believe yeah socket IO And so that is the server side JavaScript That feel weird to say so server side JavaScript still. Yeah, I know it's been around forever for PHP we have something called ratchet and This is web sockets for PHP It's a library It's got hooks for it has a web socket server built in it has an HTTP server to do the 426 upgrade and It's got all the events so We'll get into the events in a minute, but stuff like receiving a message sending a message So this is a really basic web socket server written that's written with ratchet and You can see the HTTP server is built in and then there's a web socket server and Then inside that is the new chat and that is the actual class that you're you build You would go and build as a as a developer and implement the interfaces So you're instantiating the object That actually runs the server the rest just gives you the functionality So don't worry if you can see if you can't see that I'll go into a little more detail in a sec But this chat class is implementing the message component interface So that means you have to implement those methods the on open on message on close on that error And I'll explain those in a second So You'll have to take my word for it, but there's an SPL storage object storage and When a New client makes a connection to the server It takes that connection that gets passed into the on open and Attaches it to the SPL object storage and so then we know who's who exactly is connected to the server And that's extra useful because I'll show you in a second. Well, and then on close is is In this case, you're doing the opposite. You're detaching it from the SPL storage So on message, this is this is a little more interesting So when we receive the message It's looping through all of the clients that are in the SPL object and If the from is not the client so if if the person sending the message is not in that list or As you loop through it the user who sent the message Doesn't get sent that message So everybody else gets the the message that was just received and then it fires it out to all the other connected clients on the other side This is so this is the client side and this is a whole lot simpler That website socket object is built into your browser So all you have to do is really implement the the on connect on open on close portions So you can actually tell if your browser is connected to the web socket server and you can maybe force it to try to reconnect or display a message to your users and all I'm doing on on message is On message is when it gets when a message gets received So all I'm doing is pre-pending something that says, you know, that's not me sending the message and then again from the client side And sorry for the jQuery. I know it's ugly but when you when you actually click the send button it takes the value of the message and Sends it to the connection. That's what con dot send is doing Now this is the part where I was going to do the demo, but we're on a flaming plane That's crashing into the ocean right now and my demo is not working So I apologize But what I wanted to show you is And I have a demo you can try this at home I'll give you the link at the end of the presentation But I have a Demo on github that you can try all this stuff out with So you fire up the the socket server and then you connect your browser to it and you know if it makes the connection great, if not it'll display an error and What's neat is if you kill the the server the web browser will actually say disconnected. I find that kind of stuff fascinating And Then you can actually open I have a client side version of that And you can open two or three different ones Connect to the same socket server and then they can all chat with each other But I don't have that so we're not going to look at that today The web protocol came about from Web sockets from the it branched out it came from the Sorry, it lost my train of thought Wham came from web sockets. They think it's a better approach to doing web sockets and What Wham gives you are two things RPC and pub sub RPC is making a specific Request to a Method that you're obviously that you're you're exposing So maybe you can say get me a list of connected clients or give me the store of the leaf game Whatever that is and then pub sub You can it's think of it like a chat You can publish things to a certain channel and everybody who subscribed to that channel will get those messages Now there's a Wham version 2 that came out about a year ago And unfortunately ratchet only supports rant Wham version 1 But that's still good enough to play with So this is what the Wham protocol gives you you get an on open similar to Similar to the other web sockets you get an on open on closed So you can still you know when somebody connects you can connect that attach that to the SPL storage or however You're you're maintaining your list of connected clients On call is for RPC calls. So if I make if I I get that information the topic means In this case that was confusing that took me like a day to figure out what not really a day, but a That's the method that's being called And then you get some parameters you can pass in so So I Let's say you call log in you'll in your topic You'll get log in and then you and then in the parameters you would pass in username and password and any other information you need to pass on subscribe and on unsubscribe so that's subscribing to a topic What do you want what do you want to happen if somebody subscribes to a topic or unsubscribes and on publish Published to a topic. So let's say I'm I'm sending something out to a topic that gets published and then we have an on-air So with RPC calls RPC calls our remote procedure calls you can call custom functions This is a one-to-one communication with a server. So this is for Instances where you need a User is going to be working On something differently from the rest of the users. So this is One-to-one communication This is stuff like communication between browsers and games and things like that and by sorry between by Communication between servers. I mean Sorry, sorry This is this is a bit of a new talk. I I rejigged it so I forget a bit of this The server can actually make a request of the browser and vice versa. That's the full duplex and Pub sub So one way to use this and I'm kind of getting into Bitcoin right now not Bitcoin But what's the other one? Ethereum and I've got servers communicating with each other and They're actually using web sockets to and They subscribe to topics so When each server Needs When when the configuration changes you can subscribe all of those servers to one topic and then fire out An upgrade request or a configuration change This is not limited to one-to-one communication. So this scales a whole lot better than RPC calls RPC remote procedure calls And this one important thing to note is that a client cannot request information outside of what's published So I worked on a Project, it's actually a game It's a training tool. I can show you later if you're you're interested But what it is is what it does is the way it used to work is it was built with Ajax and Every time every five minutes the game would save itself But what would happen between those five minutes is the browser would crash or the server would go down or you know There'd be some sort of problem and the person playing the game would lose their information So we attempted the idea was to make it so that a User could have Making it a lot more robust So we use web sockets for it so every time somebody did something on the game It would fire out a save request and then update your score The scoring would happen on the server not in the browser and it was real-time Ish because it was a whole lot faster than doing it with Ajax and there wasn't that five minute delay between the two So now that I've done that I have a few suggestions if you're looking to implement Web sockets in your application PHP just isn't good at running 24-7. I'm a PHP developer. Please don't think I hate PHP. I don't But we've had all sorts of crashes with it, and I hope to save you guys some some of that angst and and Late nights that I had We also had just random crashes and we actually had to dig into we we did a We had PHP core dumping And all sorts of fun stuff and also we had to deal with firewalls and proxies so I don't know if you can see that but that's a core dump and And That was not a fun day, but what the real problem was was the Redis read and write was the Redis server was dying and It wasn't dying. Sorry. That's that's not true There was a persistent connection between PHP and Redis and then Redis would time out because nobody was using that connection And then Redis would go away so we had to turn off persistent connections and Then if this that connection between the Web socket server and Redis went away it would reestablish the connection and We would be fine, but that that took a lot to figure out You limits anybody know what a you limit is What's a you limit excellent answer Yeah, it's by the OS Now does anybody know the default number of Files PHP can have open at any given time It's 1024 This is how many files the operating system thinks it can have open 65,535 So there's there's that disconnect between the two PHP only thinks your file handle opener high file And file handle can only go to 1,024 and so when it requests A file it crashes and sorry the reason this is an issue is because in Unix everything gets treated like a file Files or files directories are technically files And Certainly socket connections are files. So as you're opening more and more connections You need to pay attention to the you limit So the way to change that in PHP is to recompile PHP So we didn't want to do that so So Unfortunately right now we have a theoretical of limit limit of 1,024 connections per server what we did is we limited the we created a new user in on the server and we set the you limit to 1,024 to match PHP and You can actually create that those two lines in Slash ETC security slash limits Once we fixed that we had a whole heck of a lot of less problems the next problem we ran into was our game the game we built is for It's mostly used in universities and I don't know if any of you have dealt with university IT departments But they tend to be a little Yes They lock down their networks like anything So like I said before your WebSocket server is running on a port and in general Not in general a lot of the time The overzealous admins Will block anything above port 1,024 which you know makes sense But it's a problem for us So we need to we need to weigh around it So we had to be a little creative with that and I'll get into that in a second So engine X was came to the rescue We need to we want to we also wanted to load balance it We wanted to monitor it and we had to get around those firewall and proxy servers So our engine X Config is such that if you connect to if you request slash WebSocket on port 443 Engine X is actually load balancing three WebSocket servers And here's the configuration for it and we are going to switch one day to HA proxy It's just at the bottom of the list of things to do Here's the configuration for engine X so we define our Upstream sockets, so they're all on private I keys on 40,000 and If you request slash WebSocket, it's going to do a proxy pass to this upstream And it's also going to force you to do an HTTP upgrade and a connection upgrade You'll notice this line this line says if you can't see it it says least con and there are five different strategies for load balancing and least con is one of them It means the least connected Server of those three will get the next connection. There's also round Robin, which is the default one IP hash so I guess that I'm not sure what that one is Hash which again, I'm not sure what it is. That's my that's my system in job and Least time so that's the least latency whichever is the quickest You can also do stuff like server waiting So if one of those servers is be fear than the other ones you can send more connections to it There's there's all kinds of stuff you can do with that. I that's not necessarily my area So load balancing helps But what if one of those three go down it takes a certain number of failures for A node to actually be considered down by engine X So your users still might be getting down messaging So they might need to refresh or or try to reconnect We are monitoring our WebSocket servers by polling each one and we're sending just like a I built in a hello world RPC call And if you get a hello world back, you know, it's up But if you don't then we get then it sends a message to log glee and Enough log glee notifications and we know the node is down and we know to go know to go we know to go and reboot it now Because I like you guys everybody I'm gonna give you a business tip Nobody's doing WebSocket monitoring that I know of I'm sure somebody's gonna put up their hand and say I know some The big boys aren't doing WebSocket monitoring New relic supports process monitoring, but that's a little different from actually monitoring the port to make sure that the server is up So go start a WebSocket server monitoring business So that's new relic You can see our app is only using about 35 megs of memory and That's our CPU load. So that's actually that's actually from production. That's one of the servers and You can see it doesn't use a use a whole lot of resources Taking up my demo really killed only a half an hour in So WebSockets, they're you know, they're a whole lot faster than Ajax use them. They're they're a fun toy They there are some caveats Definitely use the server or sorry a library like ratchet. It gives you a whole lot of Functionality for free That code example of a Socket server that's a whole lot of work to implement that in PHP use the use ratchet use something similar to it Do know that you're running a separate server and you have to monitor that somehow if that goes down That's your connection your clients won't the the users won't be able to connect. They'll be unhappy One thing we do is if the server can't or if you can't connect to the server The application actually says sorry cannot connect and then we have a retry button So you can click that and it'll retry to it'll try to reconnect to the server Doesn't always work, but that's the idea and actually Since we implemented this, I think we've had maybe a half a dozen Incidences over the last two years of the WebSocket server being down of downtime that actually can be pointed at the WebSocket server So if you build this right You can get a whole lot of stability out of it So here's the URLs This is the WebSocket demo that I was going to Demonstrate unfortunately, I couldn't There's the link for ratchet more about the WAMP protocol and the Node.js library Are there any questions I can answer Yeah Like Sorry, I didn't explain that very well, right So the U limit The U limit is set on the operating system So you can actually change that So if you set it to 1,024, it's not going to go above a file handle of 1,024 So it matches PHP's 1,024 So what happens when PHP wants to open 1,025, want to still throw the same error about not being able to do that though? Loops around So it goes back to 0 for 1 So that's it, it'll just like if there's a file handle that was just not cleaned up, it'll go back and reuse that Yeah, it might not go back to 1, but it'll it'll Start over So the U limits by themselves don't like garbage collectors the problem and doing that will force it to try and go back around again? No, it's not garbage collection. It's It might try to hand PHP might ask for a file a file handle and You know the operating system might hand sorry And so it crashes I was thinking like even with the heart the limit there that force to go back to zero again It's like but what if zero is already hell? Well, it'll it'll increment it'll the operating system knows what file handles are open So it's it's gonna decide what file handle to hand PHP when it when PHP requests a new file handle If there were still like if it was still trying to open 1,025 Or had that open at once and none of them were free up to use again Well, that's why the theoretical limit is about a thousand users. No, that's a good question That is exactly where load balancing comes into play so we have three servers We don't come anywhere near 3,000 users at a given time. We maybe have a hundred on each server It would be Yeah, we should probably use this because of Since we're being recorded Thank you Yeah, so I know that people who were doing this a few years back With triple they were putting no JS in front of it. Yeah, and no JS Since it's asynchronous Seem to be pretty good at handling ridiculous and large numbers of Web sockets and Then there was some kind of proxy game that Went back to How exactly they did that Is that still a strategy that people use? so so I was doing some really researching for this talk surprise and Trello uses it and They found the there's a blog post by Joel Spalski about Web sockets And he talks about how socket IO can only handle about 10,000 users per node So they still have those problems with With node That was one of the things we considered doing When building our game is going through a node JS socket server. The reason we didn't is because We wanted to use some of the functionality in our legacy PHP app And we didn't want to build an API like that seemed like a whole lot of work to build an API just to talk to this back and forth and at the time the my SQL driver for node JS was Flaky at best it was still immature and I know it's gotten a lot better since then So that kind of limited us with what we could do it is a strategy if it works for you great It's picking your point absolutely it is I Don't like extra hops. I like as simple as possible one hop between the client and the server So that's why I took that approach I don't know I wasn't prepared for that question would I go for that You know what considering the success of the application and it does run and it runs really well I probably would and we haven't had a whole lot of breakdowns So yeah, yeah, I would Sorry So the application is the site so you send You send a request to the server and then the server says hold on I'm gonna I'll get back to you and Then once the server decides what information and that can come from anywhere can come from php You can come from cold fusion it can come from whatever you want, and then it sends it back It's just responding to other people so it's your that that request is going over and over again So you make the request it returns information you make the quest again and wait for More data Yes, yes, exactly anything else Yep Yeah, you do So this is server side and you're gonna get it'll trigger the on-close event I Think you would have to build that into the application Oh, so you know what sorry, that's not true You're gonna get You can get an on error message, and I'm sorry. This is tiny But you will get an error notification if something goes catastrophically wrong. Yep That's and actually this is at the top of my it's pinned at the top of my Twitter account. So if you Forget to do that You can just go to my Twitter and it's there It'll this will be up on YouTube So since your application's been long-lived and I was wondering if you ever had like the migration like it's 5-7 or We're still on PHP 5 Just because we haven't tested the code base on 7 yet, so I don't know yet. I'm a little anxious about that Yeah Yeah It could yeah, there's some interesting messaging going on behind the scenes and ratchet Did I miss anything anybody? All right. Thanks very much