Created
March 1, 2018 06:55
-
-
Save songcser/00055242ec55bf46471927ce42c0248e to your computer and use it in GitHub Desktop.
使用websocket和redis搭建聊天室
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<title></title> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<style type="text/css"> | |
body {padding: 0; margin: 0;} | |
#chat { | |
height: calc(100vh - 71px); | |
overflow-y: scroll; | |
padding: 10px; | |
box-sizing: border-box; | |
} | |
#chat a { | |
color: black; | |
font-weight: bold; | |
text-decoration: none; | |
} | |
.message-form { | |
height: 20px; | |
padding: 10px; | |
} | |
.message-form input { | |
height: 20px; | |
} | |
.message-form input.message-content { | |
width: calc(100% - 60px); | |
} | |
</style> | |
<script type="text/javascript"> | |
function appendMessage(sender, text) { | |
if (text.length < 1) return; | |
var chatContainer = document.getElementById('chat') | |
var messageElement = document.createElement('div') | |
messageElement.innerHTML = '<a href="#" onclick="showProfile(this, \'' + sender + '\'); return false">' + sender + '</a>' | |
+ '<div>' + text + '</div>' | |
chatContainer.appendChild(messageElement) | |
chatContainer.scrollTop = chatContainer.scrollHeight; | |
} | |
window.onload = function() { | |
socket = new WebSocket(location.protocol.replace('http', 'ws') + '//' + location.host + '/chat'); | |
this.socket.onmessage = function(event) { | |
var data = JSON.parse(event.data) | |
appendMessage(data.user, data.message) | |
} | |
} | |
function send(message) { | |
socket.send(JSON.stringify({ | |
message: message | |
})) | |
} | |
</script> | |
</head> | |
<body> | |
<div id="chat"> | |
</div> | |
<form class="message-form" onsubmit="send(this.content.value); this.content.value = ''; return false"> | |
<input type="text" name="content" class="message-content"> | |
<input type="submit" value="보내기"> | |
</form> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import json | |
import uuid | |
import asyncio | |
import asyncio_redis | |
from aiohttp import web | |
host = '127.0.0.1' | |
port = 6379 | |
# use gunicorn run server | |
# gunicorn chatserver2:app --bind localhost:8060 --worker-class aiohttp.GunicornWebWorker -w 4 | |
class WebsocketHandler: | |
async def handle(self, request): | |
userid = uuid.uuid4().hex | |
ws = web.WebSocketResponse() | |
await ws.prepare(request) | |
await asyncio.gather(self.handle_publish(ws, userid), self.handle_subscribe(ws, userid)) | |
return ws | |
async def handle_publish(self, ws, userid): | |
connection = await asyncio_redis.Connection.create(host=host, port=port) | |
try: | |
while True: | |
msg = await ws.receive() | |
data = json.loads(msg.data) | |
data['user'] = userid | |
# Publish to a channel | |
await connection.publish('room1', json.dumps(data)) | |
finally: | |
connection.close() | |
async def handle_subscribe(self, ws, userid): | |
connection = await asyncio_redis.Connection.create('localhost', 6379) | |
try: | |
# Subscribe to a channel. | |
subscriber = await connection.start_subscribe() | |
await subscriber.subscribe(['room1']) | |
while True: | |
reply = await subscriber.next_published() | |
data = json.loads(reply.value) | |
await ws.send_json(data) | |
finally: | |
connection.close() | |
async def index(request): | |
html = open('index.html', 'r').read() | |
return web.Response(body=html, content_type='text/html') | |
handler = WebsocketHandler() | |
app = web.Application() | |
app.router.add_get('/', index) | |
app.router.add_get('/chat', handler.handle) | |
def main(): | |
web.run_app(app, port=8060) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment