本节目录:

(一)笔记总结;

(二)gevent-websocket+flask+javascript实现WS即时通信

  (1)无昵称群聊

  (2)有昵称群聊

  (3)私聊

三种通信模型简述: 

(1)轮询:
客户端周期性不间断高频率的给服务器发送请求:
客户端请求--服务器响应--断开连接,请求次数QPS比较频繁,对客户端和服务器的配置要求比较高
(2)长轮询:
客户端周期性不间断的给服务器发送请求:
客户端与服务器建立的连接会保持一定时间,因此请求相对不会特别频繁
(3)长连接:
客户端与服务端建立连接后,如果不是特殊原因(客户端主动断开,服务器故障)连接会一直保持
同时通过多线程进行IO多路复用技术解决并发问题

flask中基于gevent-websocket的IO多路复用技术进行长连接通信:  

(1)基于gevent-websocket的IO多路复用长连接通信,需要导入一下模块:
#pip install gevent-websocket导入IO多路复用模块
from geventwebsocket.handler import WebSocketHandler #提供WS(websocket)协议处理
from geventwebsocket.server import WSGIServer #websocket服务承载
#WSGIServer导入的就是gevent.pywsgi中的类
# from gevent.pywsgi import WSGIServer
from geventwebsocket.websocket import WebSocket #websocket语法提示
(2)路由视图函数中的处理必须通过request.environ.get('wsgi.websocket')获取与客户端的ws连接client_socket:
 #websocket协议通信如下(http请求正常处理即可)
@app.route()
def func():
client_socket=request.environ.get('wsgi.websocket')
while 1:
client_socket.recive()
...
client_socket.send(str)
...
(3)flask项目启动如下:
WSGIServer默认处理的是http请求,路由视图中可以正常使用http,
但是在使用ws协议时务必在视图函数通过request.environ.get('wsgi.websocket')获取与客户端的ws连接client_socket,
通过连接client_socket进行client_socket.recive()/client_socket.send()通信,这连个方法会对字符串自动进行编解码)
http_server=WSGIServer(('192.168.16.14',8888),application=app,handler_class=WebSocketHandler。
http_server.serve_forever()
(4)前端页面使用js进行WS(websocket)请求:
浏览器提供了websocket客户端,直接new创建websocket连接ws,
(ws状态码0表示已创建未连接,1表示已连接保持中,2表示客户端主动断开连接,3表示服务端断开连接),
通过ws.onmessage=function (MessageEvent){}监听执行回调函数获取信息MessageEvent.data,
通过ws.send()发送信息。
<script>
var ws = new WebSocket('ws://192.168.16.14:8888/websocket');
ws.onmessage = function (MessageEvent) {
console.log(MessageEvent);
console.log(MessageEvent.data);
}; function send() {
var msg = document.getElementById('msg').value;
ws.send(msg);
}
</script>

http请求协议和websocket请求协议的请求原数据request.environ和请求头部信息request.headers比较:
http-environ:

{
'GATEWAY_INTERFACE': 'CGI/1.1', 'SERVER_SOFTWARE': 'gevent/1.4 Python/3.6',
'SCRIPT_NAME': '', 'wsgi.version': (1, 0),
'wsgi.multithread': False, 'wsgi.multiprocess': False,
'wsgi.run_once': False, 'wsgi.url_scheme': 'http',
'wsgi.errors': <_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>,
'SERVER_NAME': 'PC-Yang', 'SERVER_PORT': '', 'REQUEST_METHOD': 'GET',
'PATH_INFO': '/websocket', 'QUERY_STRING': '', 'SERVER_PROTOCOL': 'HTTP/1.1',
'REMOTE_ADDR': '192.168.16.14', 'REMOTE_PORT': '', 'HTTP_HOST': '192.168.16.14:8888',
'HTTP_CONNECTION': 'keep-alive', 'HTTP_PRAGMA': 'no-cache', 'HTTP_CACHE_CONTROL': 'no-cache',
'HTTP_UPGRADE_INSECURE_REQUESTS': '',
'HTTP_USER_AGENT': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36',
'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
'HTTP_ACCEPT_ENCODING': 'gzip, deflate', 'HTTP_ACCEPT_LANGUAGE': 'zh-CN,zh;q=0.9',
'wsgi.input': <gevent.pywsgi.Input object at 0x03A9DC00>,
'wsgi.input_terminated': True, 'werkzeug.request': <Request 'http://192.168.16.14:8888/websocket' [GET]>
}

http-environ

http-headers:

'''
Host: 192.168.16.14:8888
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
'''

http-headers

websocket-environ: 'wsgi.websocket': <geventwebsocket.websocket.WebSocket object at 0x03A9DC00>,websocket连接

'''
{
'GATEWAY_INTERFACE': 'CGI/1.1', 'SERVER_SOFTWARE': 'gevent/1.4 Python/3.6',
'SCRIPT_NAME': '', 'wsgi.version': (1, 0), 'wsgi.multithread': False,
'wsgi.multiprocess': False, 'wsgi.run_once': False, 'wsgi.url_scheme': 'http',
'wsgi.errors': <_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>,
'SERVER_NAME': 'PC-Yang', 'SERVER_PORT': '8888', 'REQUEST_METHOD': 'GET',
'PATH_INFO': '/websocket', 'QUERY_STRING': '', 'SERVER_PROTOCOL': 'HTTP/1.1',
'REMOTE_ADDR': '192.168.16.14', 'REMOTE_PORT': '61591', 'HTTP_HOST': '192.168.16.14:8888',
'HTTP_CONNECTION': 'Upgrade', 'HTTP_PRAGMA': 'no-cache', 'HTTP_CACHE_CONTROL': 'no-cache',
'HTTP_USER_AGENT': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36',
'HTTP_UPGRADE': 'websocket', 'HTTP_ORIGIN': 'http://192.168.16.14:8888', 'HTTP_SEC_WEBSOCKET_VERSION': '13',
'HTTP_ACCEPT_ENCODING': 'gzip, deflate', 'HTTP_ACCEPT_LANGUAGE': 'zh-CN,zh;q=0.9',
'HTTP_SEC_WEBSOCKET_KEY': 'Oyfq0MCEBnsypKstjjRvYg==',
'HTTP_SEC_WEBSOCKET_EXTENSIONS': 'permessage-deflate; client_max_window_bits',
'wsgi.input': <gevent.pywsgi.Input object at 0x03A9DCA8>,
'wsgi.input_terminated': True, 'wsgi.websocket_version': '13', 'wsgi.websocket': <geventwebsocket.websocket.WebSocket object at 0x03A9DC00>, 'werkzeug.request': <Request 'http://192.168.16.14:8888/websocket' [GET]>
}
'''

websocket-environ

websocket-headers:     Upgrade: websocket   #websocket请求中的标识

'''
Host: 192.168.16.14:8888
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36 Upgrade: websocket #websocket请求中的标识 Origin: http://192.168.16.14:8888
Sec-Websocket-Version: 13
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Sec-Websocket-Key: Oyfq0MCEBnsypKstjjRvYg==
Sec-Websocket-Extensions: permessage-deflate; client_max_window_bits
'''

websocket-headers

(1)基于websocket+flask实现的群聊无昵称即时通信

  flask_websocket(MUC_Nonick).py  

 '''
基于websocket+flask实现的群聊无昵称即时通信
设计列表client_list = []来存储客户端与服务器的连接,
服务收到任意客户端的信息(信息时),对连接存储列表进行遍历获取每个连接,直接进行转发
'''
from flask import Flask, render_template, request # pip install gevent-websocket导入IO多路复用模块
from geventwebsocket.handler import WebSocketHandler # 提供WS(websocket)协议处理
from geventwebsocket.server import WSGIServer # websocket服务承载
# WSGIServer导入的就是gevent.pywsgi中的类
# from gevent.pywsgi import WSGIServer
from geventwebsocket.websocket import WebSocket # websocket语法提示 app = Flask(__name__) # @app.route('/websocket')
# 多个客户端可以同时给falsk服务端发送ws协议的信息
# def websocket():
# client_socket=request.environ.get('wsgi.websocket') #type:WebSocket
# while 1:
# msg_from_cli=client_socket.receive()
# print(msg_from_cli)
# 多个客户端可以同时给falsk服务端发送ws协议的信息,同时服务端将信息转送到每个客户端页面,实现多人聊天室即时通信
client_list = [] @app.route('/websocket')
def websocket():
client_socket = request.environ.get('wsgi.websocket') # type:WebSocket
client_list.append(client_socket)
# print(len(client_list), client_list)
while 1:
msg_from_cli = client_socket.receive()
# print(msg_from_cli)
#收到任何一个客户端的信息都进行全部转发(注意如果某个客户端连接断开,在遍历发送时连接不存在会报错,需要异常处理)
for client in client_list:
try:
client.send(msg_from_cli)
except Exception as e:
continue @app.route('/chat')
def chat():
return render_template('MUC_Nonick.html') if __name__ == '__main__':
# app.run('192.168.16.14',8888,debug=True)
http_server = WSGIServer(('192.168.16.14', 8888), application=app, handler_class=WebSocketHandler)
http_server.serve_forever()

flask_websocket(MUC_Nonick).py

  MUC_Nonick.html  

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>多用户聊天无昵称</title>
</head>
<body>
<div id="chat_room">
<p>请输入聊天内容:<input type="text" id="msg">
<button id="send" onclick="send()">发送</button>
</p>
<div id="chat_content"></div>
</div>
</body>
<script type="application/javascript">
var ws = new WebSocket('ws://192.168.16.14:8888/websocket');
ws.onmessage = function (MessageEvent) {
//console.log(MessageEvent);
//console.log(MessageEvent.data);
var time=new Date();
var t= time.toLocaleString();
var p=document.createElement("p");
p.innerText="("+t+")"+MessageEvent.data;
document.getElementById('chat_content').appendChild(p);
}; function send() {
var msg = document.getElementById('msg').value;
ws.send(msg);
}
</script>
</html>

MUC_Nonick.html

(2)基于websocket+flask实现的群聊有昵称即时通信

  版本一:通过动态路有参数获取客户端昵称:

  flask_websocket(MUC_nick_route).py  

 '''
基于websocket+flask实现的群聊即时通信
设计字典client_dict = {}来存储{客户端的名字:客户端与服务器的连接},客户端的名字通过动态路由参数获取到,
服务器接收客户端发来的信息(经过json序列化后的字典),对存储连接信息的字典进行遍历,获取客户端的连接,直接转发
'''
from flask import Flask, render_template, request
from geventwebsocket.handler import WebSocketHandler # 提供WS(websocket)协议处理
from geventwebsocket.server import WSGIServer # websocket服务承载
from geventwebsocket.websocket import WebSocket # websocket语法提示 app = Flask(__name__) client_dict = {} @app.route('/websocket/<client_name>')#通过动态路由参数获取昵称,必须在视图函定义同名形参接收
def websocket(client_name):
client_socket = request.environ.get('wsgi.websocket') # type:WebSocket
client_dict[client_name] = client_socket
# print(len(client_dict), client_dict)
while 1:
msg_from_cli = client_socket.receive()
for client in client_dict.values():
try:
client.send(msg_from_cli)
except Exception as e:
continue @app.route('/chat')
def chat():
return render_template('MUC_nick_route.html') if __name__ == '__main__':
# app.run('192.168.16.14',8888,debug=True)
http_server = WSGIServer(('192.168.16.14', 8888), application=app, handler_class=WebSocketHandler)
http_server.serve_forever()

flask_websocket(MUC_nick_route).py

  MUC_nick_route.html

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>多用户聊天无昵称</title>
</head>
<body>
<div id="chat_room">
<p>输入昵称进入多人聊天室:<input type="text" id="client_name"></input>
<button id='login' onclick="login()">登录</button>
</p>
<p id='chat_msg' hidden="hidden">请输入聊天内容:<input type="text" id="msg">
<button id="send" onclick="send()">发送</button>
</p>
<div id="chat_content" hidden="hidden"></div>
</div>
</body>
<script type="application/javascript">
var ws = null;
var name=null; function login() {
document.getElementById('login').setAttribute('hidden', 'hidden');
document.getElementById('client_name').setAttribute('disabled', 'disabled');
document.getElementById('chat_msg').removeAttribute('hidden');
document.getElementById('chat_content').removeAttribute('hidden');
name = document.getElementById('client_name').value;
//进行WS实例化
ws = new WebSocket('ws://192.168.16.14:8888/websocket/' + name); //监听服务器发来的消息(json数据)
ws.onmessage = function (MessageEvent) {
//console.log(MessageEvent);
//console.log(MessageEvent.data);
var content_str = JSON.parse(MessageEvent.data);
var time = new Date();
var t = time.toLocaleTimeString();
var p = document.createElement("p");
p.innerText = content_str.name + "(" + t + "):" + content_str.msg;
document.getElementById('chat_content').appendChild(p);
};
}; //聊天信息发送(json数据)
function send() {
var msg = document.getElementById('msg').value;
var data = {
name: name,
msg: msg,
};
var data_json = JSON.stringify(data);
ws.send(data_json);
}
</script>
</html>

MUC_nick_route.html

 

  版本二:通过websocket接收客户端发来基于websocket发来的昵称: 

  flask_websocket(MUC_nick).py

 '''
基于websocket+flask实现的群聊即时通信
设计字典client_dict = {}来存储{客户端的名字:客户端与服务器的连接},客户端的名字通过客户端执行WS请求协议发送获取,
服务器再持续接收客户端发来的信息(经过json序列化后的字典),对存储连接信息的字典进行遍历,获取客户端的连接,直接转发
'''
from flask import Flask, render_template, request
from geventwebsocket.handler import WebSocketHandler # 提供WS(websocket)协议处理
from geventwebsocket.server import WSGIServer # websocket服务承载
from geventwebsocket.websocket import WebSocket # websocket语法提示 app = Flask(__name__) client_dict = {} @app.route('/websocket')
def websocket():
client_socket = request.environ.get('wsgi.websocket') # type:WebSocket
# print(client_socket)
client_name = client_socket.receive()
client_dict[client_name] = client_socket
# print(len(client_dict), client_dict)
while 1:
msg_from_cli = client_socket.receive()
# msg_from_cli_str=json.loads(msg_from_cli)
# print(msg_from_cli_str)
for client in client_dict.values():
try:
client.send(msg_from_cli)
except Exception as e:
continue @app.route('/chat')
def chat():
return render_template('MUC_nick.html') if __name__ == '__main__':
# app.run('192.168.16.14',8888,debug=True)
http_server = WSGIServer(('192.168.16.14', 8888), application=app, handler_class=WebSocketHandler)
http_server.serve_forever()

flask_websocket(MUC_nick).py

  MUC_nick.html  

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>多用户聊天无昵称</title>
</head>
<body>
<div id="chat_room">
<p>输入昵称进入多人聊天室:<input type="text" id="client_name"></input>
<button id='login' onclick="login()">登录</button>
</p>
<p id='chat_msg' hidden="hidden">请输入聊天内容:<input type="text" id="msg">
<button id="send" onclick="send()">发送</button>
</p>
<div id="chat_content" ></div>
</div>
</body>
<script type="application/javascript">
var ws = new WebSocket('ws://192.168.16.14:8888/websocket');
var name = null; //向服务端发送本机昵称
function login() {
document.getElementById('login').setAttribute('hidden', 'hidden');
document.getElementById('client_name').setAttribute('disabled', 'disabled');
document.getElementById('chat_msg').removeAttribute('hidden');
document.getElementById('chat_content').removeAttribute('hidden');
name = document.getElementById('client_name').value;
ws.send(name);
}; //监听服务器发来的消息(json数据)
ws.onmessage = function (MessageEvent) {
//console.log(MessageEvent);
//console.log(MessageEvent.data);
var content_str = JSON.parse(MessageEvent.data);
var time = new Date();
var t = time.toLocaleTimeString();
var p = document.createElement("p");
p.innerText = content_str.name + "(" + t + "):" + content_str.msg;
document.getElementById('chat_content').appendChild(p);
}; //聊天信息发送(json数据)
function send() {
var msg = document.getElementById('msg').value;
var data = {
name: name,
msg: msg
};
var data_json = JSON.stringify(data);
ws.send(data_json);
}
</script>
</html>

MUC_nick.html

(3)基于websocket+flask实现的私聊即时通信

  flask_websocket(Private_chat).py

 '''
基于websocket+flask实现的私聊即时通信
设计字典client_dict = {}来存储{客户端的名字:客户端与服务器的连接},客户端的名字通过动态路由参数获取到,
服务器通过客户端发来的信息(经过json序列化后的字典)中的目标客户端名字,在存储字典中获取目标客户端的连接,直接转发
'''
from flask import Flask, render_template, request
from geventwebsocket.handler import WebSocketHandler # 提供WS(websocket)协议处理
from geventwebsocket.server import WSGIServer # websocket服务承载
from geventwebsocket.websocket import WebSocket # websocket语法提示
import json app = Flask(__name__) client_dict = {} @app.route('/websocket/<client_name>') # 通过动态路由参数获取昵称,必须在视图函定义同名形参接收
def websocket(client_name):
client_socket = request.environ.get('wsgi.websocket') # type:WebSocket
client_dict[client_name] = client_socket
if client_socket:
while 1:
msg_from_cli = client_socket.receive()
to_client = json.loads(msg_from_cli).get('to_client')
client = client_dict.get(to_client)
try:
client.send(msg_from_cli)
except Exception as e:
continue @app.route('/chat')
def chat():
return render_template('Private_chat.html') if __name__ == '__main__':
http_server = WSGIServer(('192.168.16.14', 8888), application=app, handler_class=WebSocketHandler)
http_server.serve_forever()

flask_websocket(Private_chat).py

  Private_chat.html  

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>单人聊天室</title> </head>
<body>
<div id="chat_room">
<p>输入昵称进入单人聊天室:<input type="text" id="client_name"></input>
<button id='login' onclick="login()">登录</button>
</p>
<p hidden id="client_recv">收信人:<input type="text" id="to_client"></p>
<p id='chat_msg' hidden="hidden">请输入聊天内容:<input type="text" id="msg"> <button id="send" onclick="send()">发送</button>
</p>
<div id="chat_content" hidden="hidden"></div>
</div>
</body>
<script type="application/javascript">
var ws = null;
var name=null; function login() {
document.getElementById('login').setAttribute('hidden', 'hidden');
document.getElementById('client_name').setAttribute('disabled', 'disabled');
document.getElementById('chat_msg').removeAttribute('hidden');
document.getElementById('chat_content').removeAttribute('hidden');
document.getElementById('client_recv').removeAttribute('hidden'); name = document.getElementById('client_name').value;
//进行WS实例化
ws = new WebSocket('ws://192.168.16.14:8888/websocket/' + name); //监听服务器发来的消息(json数据)
ws.onmessage = function (MessageEvent) {
//console.log(MessageEvent);
//console.log(MessageEvent.data);
var content_str = JSON.parse(MessageEvent.data);
var time = new Date();
var t = time.toLocaleTimeString();
var p = document.createElement("p");
p.innerText = content_str.name + "(" + t + "):" + content_str.msg;
document.getElementById('chat_content').appendChild(p);
};
}; //聊天信息发送(json数据)
function send() {
var msg = document.getElementById('msg').value;
var to_client=document.getElementById('to_client').value;
var data = {
name: name,
msg: msg,
to_client:to_client
}; var data_json = JSON.stringify(data);
ws.send(data_json); var time = new Date();
var t = time.toLocaleTimeString();
var p = document.createElement("p");
p.innerText = name + "(" + t + "):" + msg;
document.getElementById('chat_content').appendChild(p); }
</script>
</html>

Private_chat.html

flask之gevent-websocket的IO多路复用长连接通信的更多相关文章

  1. Netty学习——通过websocket编程实现基于长连接的双攻的通信

    Netty学习(一)基于长连接的双攻的通信,通过websocket编程实现 效果图,客户端和服务器端建立起长连接,客户端发送请求,服务器端响应 但是目前缺少心跳,如果两个建立起来的连接,一个断网之后, ...

  2. 雨露均沾的OkHttp—WebSocket长连接的使用&源码解析

    前言 最近老板又来新需求了,要做一个物联网相关的app,其中有个需求是客户端需要收发服务器不定期发出的消息. 内心OS:

  3. HTTP的长连接和短连接——Node上的测试

        本文主要从实践角度介绍长.短连接在TCP层面的表现,借助Node.JS搭建后台服务,使用WinHTTP.Ajax做客户端请求测试,最后简单涉及WebSocket.     关键字:长连接.短连 ...

  4. HTTP 长连接 使用场景

    offer 80 非常多应用譬如监控.即时通信.即时报价系统都须要将后台发生的变化实时传送到client而无须client不停地刷新.发送请求. 在 多好科技的那位技术指导问我这个是由于他们做物连网, ...

  5. 网络编程懒人入门(八):手把手教你写基于TCP的Socket长连接

    本文原作者:“水晶虾饺”,原文由“玉刚说”写作平台提供写作赞助,原文版权归“玉刚说”微信公众号所有,即时通讯网收录时有改动. 1.引言 好多小白初次接触即时通讯(比如:IM或者消息推送应用)时,总是不 ...

  6. 微信硬件平台(七) 设备控制控制面板-网页sokect-mqtt长连接

    给微信硬件设备添加我们自己的控制面板. 主要问题: 1 要保证长连接,这样面板可以实时交互阴间设备,http一次性的连接模式通信不行. 面板必须是网页化的,网页就可以操作交互.不用APP和小程序. 2 ...

  7. [转]Web 通信 之 长连接、长轮询(long polling)

    本篇文章转载自Web 通信之长连接.长轮询(longpolling),版权归作者所有. 转者按:随着技术的发展,在HTML5中,可以通过WebSocket技术来完成长连接的开发,虽然如此,本文依然存在 ...

  8. day36 python学习gevent io 多路复用 socketserver *****

    ---恢复内容开始--- gevent 1.切换+保存状态 2.检测单线程下任务的IO,实现遇到IO自动切换 Gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步编程,在geven ...

  9. gevent协程、select IO多路复用、socketserver模块 改造多用户FTP程序例子

    原多线程版FTP程序:http://www.cnblogs.com/linzetong/p/8290378.html 只需要在原来的代码基础上稍作修改: 一.gevent协程版本 1. 导入geven ...

随机推荐

  1. tp5中的input助手函数

    详见手册:https://www.kancloud.cn/manual/thinkphp5/118044

  2. uniqid用法

    uniqid():妙用就是以当前时间微妙为单位,返回的唯一ID 我们可以用到密码加密和接口加密的功能上,比如 $salt = substr(uniqid(rand()), -6);//截取倒数6位$p ...

  3. Nginx四层代理

    Nginx支持四层代理 http://nginx.org/en/docs/stream/ngx_stream_core_module.html 该ngx_stream_core_module模块自1. ...

  4. Spring5参考指南:IOC容器

    文章目录 为什么使用Spring5 什么是IOC容器 配置元数据 实例化容器 XML嵌套 groovy bean定义DSL 使用容器 最近在翻译Spring Framework Documentati ...

  5. mysql不同端口的连接

    连接mysql3306端口命令 mysql -h58.64.217.120 -ushop -p123456 连接非3306端口(指定其他端口) 的命令 mysql -h58.64.217.120 -P ...

  6. Java算法之 二分搜寻法 ( 搜寻原则的代表)

    为什么80%的码农都做不了架构师?>>>   二分搜寻法 ( 搜寻原则的代表) 1.二分查找又称折半查找,它是一种效率较高的查找方法. 2.二分查找要求:(1)必须采用顺序存储结构 ...

  7. 关于LinearLayout设置权重后width或height不设置0dp的影响说明

    摘要 平时没那么注意LinearLayout布局时权重的问题,设置了权重属性后,通常建议将width或height的属性值设置为0dp,有时候设置权重后,还是习惯将width或height的属性设置为 ...

  8. Floyd —Warshall(最短路及其他用法详解)

    一.多元最短路求法 多元都求出来了,单源的肯定也能求. 思想是动态规划的思想:从任意节点A到任意节点B的最短路径不外乎2种可能,1是直接从A到B,2是从A经过若干个节点X到B.所以,我们假设Dis(A ...

  9. 金钱货币用什么类型--(Java)

    0.前言 项目中,基本上都会涉及到金钱:那么金钱用什么数据类型存储呢? 不少新人都会认为用double,因为它是双精度类型啊,或者float, 其实,float和double都是不能用来表示精确的类型 ...

  10. 最长递增子序列(Longest increasing subsequence)

    问题定义: 给定一个长度为N的数组A,找出一个最长的单调递增子序列(不要求连续). 这道题共3种解法. 1. 动态规划 动态规划的核心是状态的定义和状态转移方程.定义lis(i),表示前i个数中以A[ ...