Python makes WebSocket server instance sharing _python

Source: Internet
Author: User
Tags base64 clear screen ord pack set socket split ssh

First, at the beginning.

Using Python's simple implementation websocket server, you can display log information for remote servers in real time on the browser.

Previously made a web version of the publishing system, but did not achieve online viewing log, after each release version, you need to log on to the server to view the log, very troublesome, in order to lazy, can be a few buttons on the page to complete the work, these days to find this information, to achieve this function, a moment to see the log what, too convenient, Later can also be to the development of the log, no longer need to trouble Yun-Wei, nonsense less said, first look at the effect bar.

Second, the Code

Requirements: On the Web pop-up iframe layer to real-time display remote server log, click the Stop button, stop the log output in order to view the relevant log, click the Start button, continue to output log, point Close button, closed the IFRAME layer.

Before implementing this function, Google has some information, found that many can only be displayed on the Web local logs, can not see the remote server log, can see the remote log is referenced by other frameworks (such as bottle,tornado) to achieve, And all of this is to rewrite the thread's Run method to achieve, because I am too technical, I do not know how to change the way I need to look, and I am using the Django Web framework, do not want to introduce other frameworks, too complicated, So use Python to simply implement the WebSocket server. Recv_data methods and Send_data are code that refers directly to others. Because of the technical problems, the code is a bit rough, but can achieve functionality on the line, first of all to use it.

Execute the following command 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 the client handshake, and then according to the IP and type sent by the client, go to the database to find the corresponding log path, with Paramiko module SSH login to the remote server Tail view log, and then push to the browser, The server-side complete code is as follows:

# coding:utf-8 import OS import struct import base64 import hashlib import Socket import Threading Import Paramiko def GET_SSH (IP, User, pwd): Try:ssh = Paramiko. Sshclient () Ssh.set_missing_host_key_policy (Paramiko. Autoaddpolicy ()) Ssh.connect (IP, user, pwd, timeout=15) return ssh except Exception, E:print e retu RN "False" def Recv_data (conn): # Server resolves information sent by browser Try:all_data = CONN.RECV (1024) if not Len (all_data): R Eturn False Except:pass Else:code_len = Ord (all_data[1]) & 127 if Code_len = 126:masks = All
    _data[4:8] data = all_data[8:] elif Code_len = = 127:masks = all_data[10:14] 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_str def send_data (conn, data): # Server process information sent to browser if dat A:data = str (data) Else:retUrn False token = "\x81" length = Len (data) if length < 126:token + = Struct.pack ("B", length) # struct to Pyth
  In on the module that handles the binary number, the binary stream is C, or the form of the network stream. Elif length <= 0xffff:token + = Struct.pack ("! BH ", 126, Length) Else:token + + + struct.pack ("!) BQ ", 127, Length) data = '%s%s '% (token, data) conn.send (data) return True def handshake (Conn, address, Thread_na Me): headers = {} shake = CONN.RECV (1024) if not Len (Shake): Return False print ('%s:socket start handshake N with%s:%s '% (Thread_name, address[0], address[1]) header, data = Shake.split (' \r\n\r\n ', 1) for line in HEADER.SP
    Lit (' \ r \ n ') [1:]: key, value = Line.split (': ', 1) headers[key] = value if ' Sec-websocket-key ' not in headers: Print ('%s:this socket isn't websocket, client close. '% thread_name] conn.close () return False magic_str ING = ' 258eafa5-e914-47da-95ca-c5ab0dc85b11 ' handshake_string = "http/1.1 switching protocols\r\n" \ "Up Grade:websocket\r\n "\" connection:upgrade\r\n "\" sec-websocket-accept: {1}\r\n "\" WebSocket -origin: {2}\r\n "\ websocket-location:ws://{3}/\r\n\r\n" Sec_key = headers[' Sec-websocket-key '] Res_ke y = 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:sock  Et handshaken with%s:%s success '% (Thread_name, address[0], address[1]) print ' Start transmitting data ... ' print '- ,---------' return True def dojob (conn, address, Thread_name):-------------------------" Hake (conn, address, Thread_name) # handshake conn.setblocking (0) # set socket to non-blocking SSH = get_ssh (' 192.168.1.1 ', ' r Oot ', ' 123456 ') # Connect to remote server ssh_t = Ssh.get_transport () chan = Ssh_t.open_session () chan.setblocking (0) # set non-blocking Ch An.exec_command (' Tail-f/var/log/messages ') While true:clientdata = Recv_data (conn) if Clientdata ' isn't ' None and ' quit ' in Clientdata: # But when the browser clicks the Stop button or the Close button, disconnect print ('%s:socket close with%s:%s '% (Thread_name, address[0), Address[1]) sen D_DATA (conn, ' Close Connect ') Conn.close () a while True:while Chan.recv_ready (): Client Data1 = RECV_DATA (conn) if clientdata1 are 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 (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 are 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 Break Def Ws_service (): index = 1 sock = Socket.socket (socket.af_inet, S Ocket. Sock_stream) Sock.bind (("127.0.0.1", 12345)) Sock.listen print (' \r\n\r\nwebsocket server start, wait for Conn
  Ect! ')
    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 = 1 Ws_service ()

The code for GET_SSH is as follows:

Import Paramiko
def get_ssh (IP, User, pwd):
  try:
    ssh = Paramiko. Sshclient ()
    ssh.set_missing_host_key_policy (Paramiko. Autoaddpolicy ())
    ssh.connect (IP, user, pwd, timeout=15) return
    ssh
  except Exception, E:
    print E return
    "False"

When you open the page, automatically connect the WebSocket server, complete the handshake, and send the IP and type to the service side, so you can see the different types of logs on different machines,

The page code is as follows:

<! DOCTYPE html>
<title>WebSocket</title>

<style>
#log {
width:440px;
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 screen when 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; Scroll bar Displays the latest data
}
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); First get the index of the current IFRAME layer
Parent.layer.close (index); Then perform the shutdown
}
</script>



<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>

The above is the entire content of this article, I hope you can enjoy

Related Article

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.