Discussion on using WebSocket Tutorial in PHP

Source: Internet
Author: User
Tags base64 base64 encode clear screen join socket strlen trim unique id
In PHP, developers need to consider more things, from the socket connection, establishment, binding, monitoring and so on all need the developer to complete the operation, for beginners, difficulty is also very large, so the idea of this article is as follows:

1, the socket agreement brief introduction

2. Introduce the connection principle between client and server

3, PHP set up the process of socket to explain

4, use a chat room as an example to explain in detail in PHP How to use the socket

A brief introduction of socket agreement

What is websocket, what are the advantages

WebSocket is a persistent protocol, as opposed to HTTP non-persistent.

To give a simple example, Http1.0 's life cycle is defined by request, which is a request, a response, for HTTP, this client-server session is over, and in http1.1, a slight improvement, that is, adding keep-alive, that is, in a Multiple request requests and multiple response accept operations can be made in an HTTP connection. However, in real-time communication, there is not much effect, HTTP can only be initiated by the client request, the server can return information, that is, the server can not actively push information to the client, can not meet the requirements of real-time communication. And websocket can be a persistent connection, that is, the client only need a handshake, the success of the continuous data communication, it is worth noting that websocket to achieve client-server Full-duplex communication, That is, the server side has data updates can be actively pushed to the client side.

Second, introduce the principle of socket connection between client and server

1, the following is a demo client and server to establish a websocket connection between the handshake part

  

2, client and server set up a socket handshake session content, that is, request and response

A, client requests information to the server when establishing WebSocket

Get/chat http/1.1
Host:server.example.com
Upgrade:websocket//Tell the server that the WebSocket protocol is now being sent
Connection:upgrade
sec-websocket-key:x3jjhmbdl1ezlkh9gbhxdw==//is a Base64 encode value, which is randomly generated by the browser to verify that the server-side return data is a WebSocket assistant
Sec-websocket-protocol:chat, Superchat
Sec-websocket-version:13
Origin:http://example.com

b, the server gets to the client request information, according to the WebSocket protocol to the data processing and return, where the sec-websocket-key to be encrypted and other operations

http/1.1 Switching protocols
Upgrade:websocket//Is still fixed, telling the client that the WebSocket protocol is about to be upgraded, not mozillasocket,lurnarsocket or shitsocket
Connection:upgrade
sec-websocket-accept:hsmrc0smlyukagmm5oppg2hagwk=//This is confirmed by the server, and after the encryption of the Sec-websocket-key, That is, client requirements to establish WebSocket authentication credentials
Sec-websocket-protocol:chat

3, Socket set up the connection schematic diagram:

  

Three, PHP to establish a socket in the process of explaining

1, in PHP, client and server to establish socket communication, first in PHP to create a socket and listen to the port information, the code is as follows:

To create a socket operation by sending the appropriate IP and port
function WebSocket ($address, $port) {
$server = Socket_create (Af_inet, Sock_stream, sol_tcp);
Socket_set_option ($server, Sol_socket, SO_REUSEADDR, 1);//1 means accept all packets
Socket_bind ($server, $address, $port);
Socket_listen ($server);
return $server;
}

2. Design a loop to suspend the WebSocket channel to receive, process and send data


Monitor the created socket loop to process the data


function Run () {


Dead loop until the socket is disconnected


while (true) {


$changes = $this->sockets;


$write =null;


$except =null;





/*


This function is the key to accepting multiple connections at the same time, and I understand it to block programs from going down.


Socket_select ($sockets, $write = null, $except = NULL, NULL);





$sockets can be understood as an array in which the file descriptor is stored. When it changes (that is, a new message or a client connection/disconnect), the Socket_select function returns and continues to execute.


$write is listening for client write data, incoming NULL is not concerned about whether there is a write change.


$except is the element in the $sockets to be excluded, and incoming null is "listening" all.


The last parameter is the timeout time


If 0: End immediately


If n>1: Then ends after n seconds, and returns in advance if a connection has a new dynamic


If null: If a connection has a new dynamic, return


*/


Socket_select ($changes, $write, $except, NULL);


foreach ($changes as $sock) {





If a new client connection comes in, the


if ($sock = = $this->master) {





Accept a socket connection


$client =socket_accept ($this->master);





A unique ID for the newly connected socket


$key =uniqid ();


$this->sockets[]= $client; To deposit a newly connected socket in a connection pool


$this->users[$key]=array (


' Socket ' => $client,//record the socket information of the newly-connected client


' Shou ' =>false//flag The socket resource does not complete the handshake


);


Otherwise 1. Disconnect socket for client, 2.client send message


}else{


$len = 0;


$buffer = ';


Read the information for the socket, note: The second parameter is the reference to receive the data, the third parameter is the length of the received data


do{


$l =socket_recv ($sock, $buf, 1000,0);


$len + + $l;


$buffer. = $buf;


}while ($l ==1000);





According to the socket in the user pool to find the appropriate $k, that is, the health ID


$k = $this->search ($sock);





If the received message length is less than 7, the client's socket is disconnected


if ($len <7) {


Disconnect the client socket and delete it in $this->sockets and $this->users


$this->send2 ($k);


Continue


}


Determine if the socket has been shaken


if (! $this->users[$k] [' Shou ']) {


If there is no handshake, the handshake is handled


$this->woshou ($k, $buffer);


}else{


This is where the client sends the message, Uncode the received information.


$buffer = $this->uncode ($buffer, $k);


if ($buffer ==false) {


Continue


}


If not empty, a message push operation is performed


$this->send ($k, $buffer);


}


}


}





}





}


3, the above server-side completion of the websocket work, waiting for the client connection, client creation WebSocket is very simple, the code is as follows:

var ws = new WebSocket ("WS://IP: Port");
Handshake Listener function
Ws.onopen=function () {
Status 1 Proof handshake successful, then send client custom name to the past
if (so.readystate==1) {
Send a message to the server after the handshake is successful
So.send (' type=add&ming= ' +n);
}
}
Error return information function
Ws.onerror = function () {
Console.log ("error");
};
Listening for server-side push messages
Ws.onmessage = function (msg) {
Console.log (msg);
}

Disconnect WebSocket Connection
Ws.onclose = function () {
WS = FALSE;
}
Four, chat room instance code

1. PHP part

<?php


Error_reporting (e_all ^ e_notice);


Ob_implicit_flush ();





Address and interface, which requires the IP and port of the server when creating a socket


$sk =new sock (' 127.0.0.1 ', 8000);





Monitor the created socket loop to process the data


$sk->run ();





Below is the sock class


Class sock{


Public $sockets; Socket connection pool, which is the client-connected socket flag


Public $users; All client-connected information, including socket, client name, etc.


Public $master; Resource of the socket, that is, the socket resource that was returned when the socket was initialized earlier





Private $SDA =array (); Data that has been received


Private $slen =array (); Total data length


Private $sjen =array (); The length of the received data


Private $ar =array (); Encryption key


Private $n =array ();





Public function __construct ($address, $port) {





Create the socket and save the socket resource in the $this->master


$this->master= $this->websocket ($address, $port);





Creating a Socket Connection pool


$this->sockets=array ($this->master);


}





Monitor the created socket loop to process the data


function Run () {


Dead loop until the socket is disconnected


while (true) {


$changes = $this->sockets;


$write =null;


$except =null;





/*


This function is the key to accepting multiple connections at the same time, and I understand it to block programs from going down.


Socket_select ($sockets, $write = null, $except = NULL, NULL);





$sockets can be understood as an array in which the file descriptor is stored. When it changes (that is, a new message or a client connection/disconnect), the Socket_select function returns and continues to execute.


$write is listening for client write data, incoming NULL is not concerned about whether there is a write change.


$except is the element in the $sockets to be excluded, and incoming null is "listening" all.


The last parameter is the timeout time


If 0: End immediately


If n>1: Then ends after n seconds, and returns in advance if a connection has a new dynamic


If null: If a connection has a new dynamic, return


*/


Socket_select ($changes, $write, $except, NULL);


foreach ($changes as $sock) {





If a new client connection comes in, the


if ($sock = = $this->master) {





Accept a socket connection


$client =socket_accept ($this->master);





A unique ID for the newly connected socket


$key =uniqid ();


$this->sockets[]= $client; To deposit a newly connected socket in a connection pool


$this->users[$key]=array (


' Socket ' => $client,//record the socket information of the newly-connected client


' Shou ' =>false//flag The socket resource does not complete the handshake


);


Otherwise 1. Disconnect socket for client, 2.client send message


}else{


$len = 0;


$buffer = ';


Read the information for the socket, note: The second parameter is the reference to receive the data, the third parameter is the length of the received data


do{


$l =socket_recv ($sock, $buf, 1000,0);


$len + + $l;


$buffer. = $buf;


}while ($l ==1000);





According to the socket in the user pool to find the appropriate $k, that is, the health ID


$k = $this->search ($sock);





If the received message length is less than 7, the client's socket is disconnected


if ($len <7) {


Disconnect the client socket and delete it in $this->sockets and $this->users


$this->send2 ($k);


Continue


}


Determine if the socket has been shaken


if (! $this->users[$k] [' Shou ']) {


If there is no handshake, the handshake is handled


$this->woshou ($k, $buffer);


}else{


This is where the client sends the message, Uncode the received information.


$buffer = $this->uncode ($buffer, $k);


if ($buffer ==false) {


Continue


}


If not empty, a message push operation is performed


$this->send ($k, $buffer);


}


}


}





}





}





Specifies that the $k corresponding socket is closed


function Close ($k) {


Disconnect the corresponding socket


Socket_close ($this->users[$k] [' socket ']);


Delete the appropriate user information


unset ($this->users[$k]);


Redefining the sockets Connection pool


$this->sockets=array ($this->master);


foreach ($this->users as $v) {


$this->sockets[]= $v [' socket '];


}


Output log


$this->e ("Key: $k close");


}





According to Sock, find the corresponding $k within the users


function Search ($sock) {


foreach ($this->users as $k => $v) {


if ($sock = = $v [' socket '])


return $k;


}


return false;


}





To create a socket operation by sending the appropriate IP and port


function WebSocket ($address, $port) {


$server = Socket_create (Af_inet, Sock_stream, sol_tcp);


Socket_set_option ($server, Sol_socket, SO_REUSEADDR, 1);//1 means accept all packets


Socket_bind ($server, $address, $port);


Socket_listen ($server);


$this->e (' Server started: '. Date (' y-m-d h:i:s '));


$this->e (' listening on: '. $address. ' Port ' $port);


return $server;


}








/*


* Function Description: The client's request to respond, that is, handshake operation


* @ $k Clien socket corresponding to the health, that is, each user has a unique $k and corresponding socket


* @ $buffer Receive all information from client requests


*/


function Woshou ($k, $buffer) {





Intercepts the value of the Sec-websocket-key and encrypts it, where the $key part of the following 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 string should be fixed


$buf = substr ($buffer, Strpos ($buffer, ' Sec-websocket-key: ') +18);


$key = Trim (substr ($buf, 0,strpos ($buf, "\ r \ n"));


$new _key = Base64_encode (SHA1 ($key.) 258eafa5-e914-47da-95ca-c5ab0dc85b11 ", true));





Return according to Protocol combination information


$new _message = "http/1.1 switching protocols\r\n";


$new _message. = "upgrade:websocket\r\n";


$new _message. = "sec-websocket-version:13\r\n";


$new _message. = "connection:upgrade\r\n";


$new _message. = "Sec-websocket-accept:". $new _key. "\r\n\r\n";


Socket_write ($this->users[$k] [' socket '], $new _message,strlen ($new _message));





Sign the client who has already shook hands


$this->users[$k] [' Shou ']=true;


return true;





}





decoding functions


function Uncode ($STR, $key) {


$mask = Array ();


$data = ';


$msg = Unpack (' h* ', $str);


$head = substr ($msg [1],0,2);


if ($head = = ' Bayi ' &&!isset ($this->slen[$key])) {


$len =substr ($msg [1],2,2);


$len =hexdec ($len);//convert hexadecimal to decimal


if (substr ($msg [1],2,2) = = ' Fe ') {


$len =substr ($msg [1],4,4);


$len =hexdec ($len);


$msg [1]=substr ($msg [1],4);


}else if (substr ($msg [1],2,2) = = ' ff ') {


$len =substr ($msg [1],4,16);


$len =hexdec ($len);


$msg [1]=substr ($msg [1],16);


}


$mask [] = Hexdec (substr ($msg [1],4,2));


$mask [] = Hexdec (substr ($msg [1],6,2));


$mask [] = Hexdec (substr ($msg [1],8,2));


$mask [] = Hexdec (substr ($msg [1],10,2));


$s = 12;


$n = 0;


}else if ($this->slen[$key] > 0) {


$len = $this->slen[$key];


$mask = $this->ar[$key];


$n = $this->n[$key];


$s = 0;


}





$e = strlen ($msg [1])-2;


for ($i = $s; $i <= $e; $i + 2) {


$data. = Chr ($mask [$n%4]^hexdec (substr ($msg [1], $i, 2));


$n + +;


}


$dlen =strlen ($data);





if ($len > 255 && $len > $dlen +intval ($this->sjen[$key)) {


$this->ar[$key]= $mask;


$this->slen[$key]= $len;


$this->sjen[$key]= $dlen +intval ($this->sjen[$key]);


$this->sda[$key]= $this->sda[$key]. $data;


$this->n[$key]= $n;


return false;


}else{


unset ($this->ar[$key], $this->slen[$key], $this->sjen[$key], $this->n[$key]);


$data = $this->sda[$key]. $data;


unset ($this->sda[$key]);


return $data;


}





}





Relative to the Uncode


function code ($MSG) {


$frame = Array ();


$frame [0] = ' 81 ';


$len = strlen ($msg);


if ($len < 126) {


$frame [1] = $len <16? ' 0 '. Dechex ($len):d Echex ($len);


}else if ($len < 65025) {


$s =dechex ($len);


$frame [1]= ' 7e '. Str_repeat (' 0 ', 4-strlen ($s)). $s;


}else{


$s =dechex ($len);


$frame [1]= ' 7f '. Str_repeat (' 0 ', 16-strlen ($s)). $s;


}


$frame [2] = $this->ord_hex ($msg);


$data = Implode (", $frame);


Return Pack ("h*", $data);


}





function Ord_hex ($data) {


$msg = ';


$l = strlen ($data);


for ($i = 0; $i < $l; $i + +) {


$msg. = Dechex (Ord ($data {$i}));


}


return $msg;


}





The user joins or the client sends the information


function Send ($k, $msg) {


Resolves the query string into a second parameter variable, as an array: Parse_str ("name=bill&age=60", $arr)


Parse_str ($msg, $g);


$ar =array ();





if ($g [' type ']== ' add ') {


The first time to add a chat name, save the name in the appropriate users


$this->users[$k] [' name ']= $g [' Ming '];


$ar [' type ']= ' add ';


$ar [' name ']= $g [' Ming '];


$key = ' all ';


}else{


Send information behavior, which $g[' key '] to show that the face of everyone or a person, is the message from the previous paragraph passed over


$ar [' Nrong ']= $g [' nr '];


$key = $g [' key '];


}


Push information


$this->send1 ($k, $ar, $key);


}





Client pushed already online for the newly joined client


function Getusers () {


$ar =array ();


foreach ($this->users as $k => $v) {


$ar []=array (' Code ' => $k, ' name ' => $v [' name ']);


}


return $ar;


}





$k sender of the Socketid $key the Socketid of the recipient, according to this socketid can find the corresponding client for message push, that is, specify the client to send


function Send1 ($k, $ar, $key = ' all ') {


$ar [' Code1 ']= $key;


$ar [' Code ']= $k;


$ar [' Time ']=date (' m-d h:i:s ');


Encode and process the sent information


$str = $this->code (Json_encode ($ar));


In the face of everyone, that is, all online send information


if ($key = = ' All ') {


$users = $this->users;


If the add represents the newly added client


if ($ar [' type ']== ' add ') {


$ar [' type ']= ' Madd ';


$ar [' Users ']= $this->getusers (); Take out all online users for display in the online user list


$str 1 = $this->code (Json_encode ($ar)); Separate code processing for new client, data is different


Send the new client himself separately, because some data is not the same


Socket_write ($users [$k] [' socket '], $str 1,strlen ($str 1));


The above has been sent to the client itself, the back is not sent again, so unset


Unset ($users [$k]);


}


Send information to other client in addition to the new client. When the volume of data is large, we should consider the problem of delay.


foreach ($users as $v) {


Socket_write ($v [' socket '], $STR, strlen ($STR));


}


}else{


Send a message individually to a person, that is, a conversation between two parties


Socket_write ($this->users[$k] [' socket '], $STR, strlen ($STR));


Socket_write ($this->users[$key] [' socket '], $STR, strlen ($STR));


}


}





User exits the push message to the client being used


function Send2 ($k) {


$this->close ($k);


$ar [' type ']= ' rmove ';


$ar [' Nrong ']= $k;


$this->send1 (False, $ar, ' all ');


}





Record log


function e ($str) {


$path =dirname (__file__). ' /log.txt ';


$str = $str. " \ n ";


Error_log ($STR, 3, $path);


Code processing


echo iconv (' Utf-8 ', ' Gbk//ignore ', $str);


}


}


?>


2. Client part

<!doctype html>


<html>


<head>


<meta charset= "Utf-8" >


<meta name= "viewport" content= "Width=device-width, initial-scale=1, User-scalable=no"/>


<TITLE>HTML5 WebSocket web chat room JavaScript php</title>


<style type= "Text/css" >


body,p{margin:0px padding:0px; font-size:14px; color: #333; font-family:arial, Helvetica, Sans-serif;}


#ltian,. rin{width:98%; margin:5px Auto;


#ltian {border:1px #ccc solid;overflow-y:auto; overflow-x:hidden; position:relative;}


#ct {margin-right:111px; Height:100%;overflow-y:auto;overflow-x: Hidden;}


#us {width:110px; overflow-y:auto; overflow-x:hidden; float:right; border-left:1px #ccc solid; height:100%; Background-color: #F1F1F1;}


#us p{padding:3px 5px; color: #08C; line-height:20px; height:20px; cursor:pointer; overflow:hidden; white-space:nowrap; Text-overflow:ellipsis;}


#us P:hover, #us p:active, #us p.ck{background-color: #069; color: #FFF;}


#us P.my:hover, #us p.my:active, #us p.my{color: #333; background-color:transparent;}


Button{float:right; width:80px; height:35px; font-size:18px;}


input{width:100% height:30px; padding:2px; line-height:20px; outline:none; border:solid 1px #CCC;}


. Rin p{margin-right:160px;}


. Rin span{float:right; padding:6px 5px 0px 5px; position:relative;}


. Rin span img{margin:0px 3px; cursor:pointer;}


. Rin span Form{position:absolute; width:25px; height:25px; overflow:hidden; opacity:0; top:5px; right:5px;}


. Rin span input{width:180px; height:25px; margin-left:-160px; Cursor:pointer}





#ct p{padding:5px; line-height:20px;}


#ct a{color: #069; cursor:pointer;}


#ct span{color: #999; margin-right:10px;}


. C2{color: #999;}


. C3{background-color: #DBE9EC; padding:5px;}


Qp{position:absolute font-size:12px; color: #666; top:5px; right:130px; text-decoration:none; color: #069;}


#ems {position:absolute; z-index:5; display:none; top:0px; left:0px; max-width:230px; Background-color: #F1F1F1; border : solid 1px #CCC; padding:5px;}


#ems img{width:44px height:44px; border:solid 1px #FFF; cursor:pointer;}


#ems Img:hover, #ems img:active{border-color: #A4B7E3;}


#ems a{color: #069; border-radius:2px; display:inline-block; margin:2px 5px; padding:1px 8px; text-decoration:none; Background-color: #D5DFFD;}


#ems a:hover, #ems a:active, #ems a.ck{color: #FFF; Background-color: #069;}


. tc{text-align:center; margin-top:5px;}


</style>


</head>





<body>


<div id= "Ltian" >


<div id= "Us" class= "JB" ></div>


<div id= "CT" ></div>


<a href= "javascript:;" class= "QP" onclick= "this.parentnode.children[1].innerhtml=" "" > Clear screen </a>


</div>


<div class= "Rin" >


<button id= "SD" > Send </button>


<span><img src= "http://www.yxsss.com/ui/sk/t.png" title= expression "id=" Imgbq "><img src=" http:// Www.yxsss.com/ui/sk/e.png "title=" Upload picture "><form><input type=" file "title=" Upload picture "id=" upimg "></form ></span>


<p><input id= "Nrong" ></p>


</div>


<div id= "EMS" ><p></p><p class= "TC" ></p></div>


<script>


if (typeof (WebSocket) = = ' undefined ') {


Alert (' Your browser doesn't support WebSocket, recommend Google Chrome or Mozilla Firefox ');


}


</script>


<script src= "Http://www.yxsss.com/ui/p/a.js" type= "Text/javascript" ></script>


<script>


(function () {


var key= ' all ', mkey;


var users={};


var url= ' ws://127.0.0.1:8000 ';


var So=false,n=false;


var lus=a.$ (' Us '), lct=a.$ (' ct ');


Function St () {


N=prompt (' Please give yourself a loud name: ');


N=n.substr (0,16);


if (!n) {


return;


}


Create a socket, note the format of the URL: ws://ip: Port


So=new WebSocket (URL);


Handshake Listener function


So.onopen=function () {


Status 1 Proof handshake successful, then send client custom name to the past


if (so.readystate==1) {


So.send (' type=add&ming= ' +n);


}


}





Handshake failed or other reason connection socket failed, clear so object and make appropriate prompt action


So.onclose=function () {


So=false;


Lct.appendchild (a.$$ (' <p class= "C2" > Exit chat Room </p>));


}





The data receives the monitor, the receiving server pushes over the information, the returned data gives MSG, then carries on the display


So.onmessage=function (msg) {


Eval (' var da= ' +msg.data);


var Obj=false,c=false;


if (da.type== ' add ') {


var obj=a.$$ (' <p> ' +da.name+ ' </p> ');


Lus.appendchild (obj);


Cuser (Obj,da.code);


obj=a.$$ (' <p><span>[' +da.time+ ']</span> welcome <a> ' +da.name+ ' </a> join </p> ');


C=da.code;


}else if (da.type== ' Madd ') {


Mkey=da.code;


Da.users.unshift ({' Code ': ' All ', ' name ': ' Everyone '});


for (Var i=0;i<da.users.length;i++) {


var obj=a.$$ (' <p> ' +da.users[i].name+ ' </p> ');


Lus.appendchild (obj);


if (Mkey!=da.users[i].code) {


Cuser (Obj,da.users[i].code);


}else{


Obj.classname= ' my ';


Document.title=da.users[i].name;


}


}


obj=a.$$ (' <p><span>[' +da.time+ ']</span> welcome ' +da.name+ ' to join </p> ');


Users.all.classname= ' CK ';


}





if (Obj==false) {


if (da.type== ' Rmove ') {


var obj=a.$$ (' <p class= ' C2 "><span>[' +da.time+ ']</span> ' +users[da.nrong].innerhtml+ ') exit chat room </p > ');


Lct.appendchild (obj);


Users[da.nrong].del ();


Delete Users[da.nrong];


}else{


Da.nrong=da.nrong.replace (/{\\ (\d+)}/g,function (a,b) {


Return ' <img src= ' sk/' +b+ '. gif ' > ';


}). replace (/^data\:image\/png;base64\,.{ 50,}$/i,function (a) {


Return ' <img src= ' +a+ ' ">";


});


Da.code the code of the person who sent the message


if (Da.code1==mkey) {


obj=a.$$ (' <p class= "C3" ><span>[' +da.time+ ']</span><a> ' +users[da.code].innerhtml+ ') </a > said to me: ' +da.nrong+ ' </p> ');


C=da.code;


}else if (da.code==mkey) {


if (da.code1!= ' all ')


obj=a.$$ (' <p class= ' C3 ' ><span>[' +da.time+ ']</span> me to <a> ' +users[da.code1].innerhtml+ ' </a> said: ' +da.nrong+ ' </p> ');


Else


obj=a.$$ (' <p><span>[' +da.time+ ']</span> i to <a> ' +users[da.code1].innerhtml+ ' </a> said: ' +da.nrong+ ' </p> ');


C=da.code1;


}else if (da.code==false) {


obj=a.$$ (' <p><span>[' +da.time+ ']</span> ' +da.nrong+ ' </p> ');


}else if (da.code1) {


obj=a.$$ (' <p><span>[' +da.time+ ']</span><a> ' +users[da.code].innerhtml+ ' </a> pair ' + users[da.code1].innerhtml+ ' said: ' +da.nrong+ ' </p> ');


C=da.code;


}


}


}


if (c) {


Obj.children[1].onclick=function () {


Users[c].onclick ();


}


}


Lct.appendchild (obj);


Lct.scrolltop=math.max (0,lct.scrollheight-lct.offsetheight);





}


}


a.$ (' SD '). Onclick=function () {


if (!SO) {


Return St ();


}


var da=a.$ (' Nrong '). Value.trim ();


if (da== ') {


Alert (' content cannot be empty ');


return false;


}


a.$ (' Nrong '). value= ';


So.send (' nr= ' +esc (DA) + ' &key= ' +key);


}


a.$ (' Nrong '). Onkeydown=function (e) {


var e=e| | Event


if (e.keycode==13) {


a.$ (' SD '). onclick ();


}


}


function Esc (DA) {


Da=da.replace (/</g, ' < '). Replace (/>/g, ' > '). replace (/\ "/g, '");


Return encodeURIComponent (DA);


}


function Cuser (t,code) {


users[code]=t;


T.onclick=function () {


T.parentnode.children.rcss (' ck ', ');


T.rcss (', ' ck ');


Key=code;


}


}


a.$ (' Ltian '). style.height= (document.documentelement.clientheight-70) + ' px ';


St ();








var bq=a.$ (' Imgbq '), ems=a.$ (' EMS ');


var L=80,r=4,c=5,s=0,p=math.ceil (l/(r*c));


var pt= ' sk/';


Bq.onclick=function (e) {


var e=e| | Event


if (!SO) {


Return St ();


}


ems.style.display= ' block ';


Document.onclick=function () {


GB ();


}


CT ();


Try{e.stoppropagation ();} catch (o) {}


}





for (Var i=0;i<p;i++) {


var a=a.$$ (' <a href= "javascript:;" > ' + (i+1) + ' </a> ');


Ems.children[1].appendchild (a);


EF (a,i);


}


Ems.children[1].children[0].classname= ' CK ';





function ct () {


var Wz=bq.weiz ();


With (Ems.style) {


top=wz.y-242+ ' px ';


left=wz.x+bq.offsetwidth-235+ ' px ';


}


}





Function EF (t,i) {


T.onclick=function (e) {


var e=e| | Event


S=i*r*c;


Ems.children[0].innerhtml= ';


HH ();


This.parentNode.children.rcss (' ck ', ');


This.rcss (', ' ck ');


Try{e.stoppropagation ();} catch (o) {}


}


}





function hh () {


var z=math.min (l,s+r*c);


for (Var i=s;i<z;i++) {


var a=a.$$ (' <img src= "' +pt+i+ '. gif ' > ');


HH1 (A,i);


Ems.children[0].appendchild (a);


}


CT ();


}





function HH1 (t,i) {


T.onclick=function (e) {


var e=e| | Event


a.$ (' Nrong '). value+= ' {\ \ ' +i+ '} ';


if (!e.ctrlkey) {


GB ();


}


Try{e.stoppropagation ();} catch (o) {}


}


}





function GB () {


Ems.style.display= ';


a.$ (' Nrong '). focus ();


Document.onclick= ';


}


HH ();


A.on (window, ' Resize ', function () {


a.$ (' Ltian '). style.height= (document.documentelement.clientheight-70) + ' px ';


CT ();


})





var fimg=a.$ (' upimg ');


var img=new Image ();


var dw=400,dh=300;


A.on (fimg, ' Change ', function (EV) {


if (!SO) {


St ();


return false;


}


if (key== ' all ') {


Alert (' Only private chat due to resource constraints ');


return false;


}


var f=ev.target.files[0];


if (F.type.match (' image.* ')) {


var r = new FileReader ();


R.onload = function (e) {


Img.setattribute (' src ', e.target.result);


};


R.readasdataurl (f);


}


});


Img.onload=function () {


Ih=img.height,iw=img.width;


if (Iw/ih > Dw/dh && iw > DW) {


IH=IH/IW*DW;


IW=DW;


}else if (ih > DH) {


IW=IW/IH*DH;


IH=DH;


}


var rc = a.$$ (' canvas ');


var ct = rc.getcontext (' 2d ');


RC.WIDTH=IW;


Rc.height=ih;


Ct.drawimage (IMG,0,0,IW,IH);


var da=rc.todataurl ();


So.send (' nr= ' +esc (DA) + ' &key= ' +key);


}





})();


</script>


</body>


</html>

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.