Create a websocket server instance with python, and share the websocket with python.

Source: Internet
Author: User
Tags set socket

Create a websocket server instance with python, and share the websocket with python.

I. Start

Using python to implement websocket server, you can display the log information of the remote server in real time on the browser.

A web Version Release System was developed before, but the system did not view logs online. After each release, You need to log on to the server to view logs. This is very troublesome. In order to be lazy, you can click a few buttons on the page to complete the work. In the past few days, you have searched for the information and implemented this function. It is too convenient to instantly view the log or something, you can also query logs for developers in the future, so you don't have to worry about O & M any more. Let's just look at the results first.

Ii. Code

Requirement: the iframe layer pops up on the web to display logs of remote servers in real time. Click the stop button to stop log output to view related logs. Click the start button to continue to output logs, click close to close the iframe layer.

Before implementing this function, google found that many local logs can only be displayed on the web, and remote server logs cannot be viewed, remote logs can be viewed by referencing other frameworks (such as bottle and tornado), and all these are implemented by rewriting the thread run method. Because of my technical expertise, I don't know how to change it to what I need, and I use the django web framework. I don't want to introduce other frameworks, so it's too complicated. So I use python to implement websocket server simply. The recv_data method and send_data method directly reference others' code. Due to technical issues, the Code is a bit rough, but the function can be implemented. We will use it first.

Run the following commands to start django and websocketserver:

nohup python manage.py runserver 10.1.12.110 &nohup python websocketserver.py &

Start websocket, receive the request, start a thread and shake hands with the client, and then find the corresponding Log Path in the database based on the ip address and type sent by the client, use the paramiko module ssh to log on to the remote server and run tail to view logs. Then, push the logs to the browser. The complete server code is as follows:

# Coding: utf-8import osimport structimport base64import hashlibimport socketimport threadingimport paramikodef get_ssh (ip, user, pwd): try: ssh = paramiko. SSHClient () ssh. set_missing_host_key_policy (paramiko. autoAddPolicy () ssh. connect (ip, 22, user, pwd, timeout = 15) return ssh failed t Exception, e: print e return "False" def recv_data (conn ): # The server parses the information sent by the browser. try: all_data = conn. recv (1024) if not len (All_data): return False failed T: pass else: code_len = ord (all_data [1]) & 127 if code_len = 126: masks = all_data [] data = all_data [8:] elif code_len = 127: masks = all_data [] data = all_data [14:] else: masks = all_data [2: 6] data = all_data [6:] raw_str = "" I = 0 for d in data: raw_str + = chr (ord (d) ^ ord (masks [I % 4]) I + = 1 return raw_strdef send_data (conn, data): # The server processes the information sent to the browser if Data: data = str (data) else: return False token = "\ x81" length = len (data) if length <126: token + = struct. pack ("B", length) # struct is a module for processing binary numbers in Python, And the binary stream is in the form of a C or network stream. Elif length <= 0 xFFFF: token + = struct. pack ("! BH ", 126, length) else: token + = struct. pack ("! BQ ", 127, length) data = '% s % s' % (token, data) conn. send (data) return Truedef handshake (conn, address, thread_name): headers ={} shake = conn. recv (1024) if not len (shake): return False print ('% s: Socket start handshaken with % s: % s' % (thread_name, address [0], address [1]) header, data = shake. split ('\ r \ n \ r \ n', 1) for line in header. split ('\ r \ n') [1:]: key, value = line. split (':', 1) headers [key] = Value if 'sec-WebSocket-key' not in headers: print ('% s: This socket is not websocket, client close. '% thread_name) conn. close () return False MAGIC_STRING = '258eafa5-E914-47DA-95CA-C5AB0DC85B11 'HANDSHAKE_STRING = "HTTP/1.1 101 Switching Protocols \ r \ n" \ "Upgrade: websocket \ r \ n" \ "Connection: upgrade \ r \ n "\" Sec-WebSocket-Accept: {1} \ r \ n "\" WebSocket-Origin: {2} \ r \ n "\" WebSocket-Location: Ws: // {3}/\ r \ n "sec_key = headers ['sec-WebSocket-key'] res_key = base64.b64encode (hashlib. sha1 (sec_key + MAGIC_STRING ). digest () str_handshake = HANDSHAKE_STRING.replace ('{1}', res_key ). replace ('{2}', headers ['origin']). replace ('{3}', headers ['host']) conn. send (str_handshake) print ('% s: Socket handshaken with % s: % s success' % (thread_name, address [0], address [1]) print 'start transmitting d Ata... 'print '--'Return Truedef dojob (conn, address, thread_name): handshake (conn, address, thread_name) # handshake conn. setblocking (0) # set socket to non-blocking ssh = get_ssh ('2017. 168.1.1 ', 'root', '123') # connect to the remote server ssh_t = ssh. get_transport () chan = ssh_t.open_session () chan. setblocking (0) # Set non-blocking chan.exe c_command ('Tail-f/var/log/messages ') while Tr Ue: clientdata = recv_data (conn) if clientdata is not None and 'quit' in clientdata: # However, when the browser clicks the stop or close button, the print ('% s: socket close with % s: % s' % (thread_name, address [0], address [1]) send_data (conn, 'close connection') conn. close () break while True: while chan. recv_ready (): clientdata1 = recv_data (conn) if clientdata1 is not None and 'quit' in clientdata1: print ('% s: Socket close with % s: % S' % (thread_name, address [0], address [1]) send_data (conn, 'close connect ') conn. close () break log_msg = chan. recv (1, 10000 ). strip () # receive log information print log_msg send_data (conn, log_msg) if chan. exit_status_ready (): break clientdata2 = recv_data (conn) if clientdata2 is not None and 'quit' in clientdata2: print ('% s: Socket close with % s: % s' % (thread_name, address [0], address [1]) send_data (conn, 'close Connect ') conn. close () break breakdef ws_service (): index = 1 sock = socket. socket (socket. AF_INET, socket. SOCK_STREAM) sock. bind ("127.0.0.1", 12345) sock. listen (100) print ('\ r \ n \ r \ nWebsocket server start, wait for connect! ') Print'---'while True: connection, address = sock. accept () thread_name = 'thread _ % s' % index print ('% s: Connection from % s: % s' % (thread_name, address [0], address [1]) t = threading. thread (target = dojob, args = (connection, address, thread_name) t. start () index + = 1ws_service ()

The get_ssh code is as follows:

import paramikodef get_ssh(ip, user, pwd):  try:    ssh = paramiko.SSHClient()    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())    ssh.connect(ip, 22, user, pwd, timeout=15)    return ssh  except Exception, e:    print e    return "False"

When the page is opened, the websocket server is automatically connected, the handshake is completed, and the ip address and type are sent to the server. Therefore, you can view logs of different types and machines,

The page code is as follows:

<! DOCTYPE html>
<Html>
<Head>
<Title> WebSocket </title>

<Style>
# Log {
Width: pixel PX;
Height: 200px;
Border: 1px solid #7F9DB9;
Overflow: auto;
}
Pre {
Margin: 0 0 0;
Padding: 0;
Border: hidden;
Background-color: # 0c0c0c;
Color: #00ff00;
}
# Btns {
Text-align: right;
}
</Style>

<Script>
Var socket;
Function init (){
Var host = "ws: /// 127.0.0.1: 12345 /";

Try {
Socket = new WebSocket (host );
Socket. onopen = function (){
Log ('connected ');
};
Socket. onmessage = function (msg ){
Log (msg. data );
Var obje = document. getElementById ("log"); // clear the screen when there are too many logs
Var textlength = obje. scrollHeight;
If (textlength> 10000 ){
Obje. innerHTML = '';
}
};
Socket. onclose = function (){
Log ("Lose Connection! ");
$ ("# Start"). attr ('Disabled ', false );
$ ("# Stop"). attr ('Disabled ', true );
};
$ ("# Start"). attr ('Disabled ', true );
$ ("# Stop"). attr ('Disabled ', false );
}
Catch (ex ){
Log (ex );
}
}
Window. onbeforeunload = function (){
Try {
Socket. send ('quit ');
Socket. close ();
Socket = null;
}
Catch (ex ){
Log (ex );
}
};
Function log (msg ){
Var obje = document. getElementById ("log ");
Obje. innerHTML + = '<pre> <code>' + msg + '</code> </pre> ';
Obje. scrollTop = obje. scrollHeight; // the latest data is displayed on the scroll bar.
}
Function stop (){
Try {
Log ('close connection! ');
Socket. send ('quit ');
Socket. close ();
Socket = null;
$ ("# Start"). attr ('Disabled ', false );
$ ("# Stop"). attr ('Disabled ', true );
}
Catch (ex ){
Log (ex );
}
}
Function closelayer (){
Try {
Log ('close connection! ');
Socket. send ('quit ');
Socket. close ();
Socket = null;
}
Catch (ex ){
Log (ex );
}
Var index = parent. layer. getFrameIndex (window. name); // obtain the index of the current iframe layer first.
Parent. layer. close (index); // close it.
}
</Script>

</Head>


<Body onload = "init ()">
<Div>
<Div>
<Div id = "log"> </div>
<Br>
</Div>
</Div>
<Div>
<Div>
<Div id = "btns">
<Input disabled = "disabled" type = "button" value = "start" id = "start" onclick = "init ()">
<Input disabled = "disabled" type = "button" value = "stop" id = "stop" onclick = "stop ()">
<Input type = "button" value = "close" id = "close" onclick = "closelayer ()">
</Div>
</Div>
</Div>
</Body>

</Html>

The above is all the content of this article. I hope you will like it.

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.