Ứng dụng Python

Xây dựng hệ thống chat real time với aiohttp - Cài đặt aiohttp

Đăng bởi - Ngày 25-04-2018

Chào các bạn, bài viết hôm nay mình sẽ đổi gió một chút. Chúng ta sẽ viết một ứng dụng chat real time đơn giản sử dụng module aiohttp. Các bạn có thể tham khảo thêm tài liệu về aiohttp tại đây:

Giới thiệu sơ lược về aiohttp

Asyncio là một thư viện dùng để viết các ứng dụng không đồng bộ, đây là cách hiệu quả nhất để thực hiện mộng mạng máy chủ phải xử lý nhiều tác vụ cùng một lúc. Và Andrew Svetlov, một Python Core Developer người Nga đã viết một package aiohttp, dùng để tạo HTTP client/ server cho asyncio. Aiohttp support cả server websocket và client websocket.

Cài đặt aiohttp

Ok, bây giờ tới phần cài đặt. Các bạn có thể cài đặt trực tiếp trên Python luôn, nhưng mình khuyên các bạn nên làm trên virtualenv, việc tạo thói quen sử dụng virtualenv sẽ giúp bạn quản lý các applications dễ dàng hơn, bảo trì hoặc nâng cấp mà không ảnh hưởng đến các applications khác.

user@server: cd /var/projects/aiohttp/ #1
user@server aiohttp: virtualenv pyenv #2
Using base prefix '/usr'
New python executable in /var/projects/flask/asyncio/test/pyenv/bin/python
Installing setuptools, pip, wheel...done.
user@server aiohttp: source pyenv/bin/activate #3
user@server aiohttp: mkdir -p simplechat-aiohttp #4
user@server aiohttp: cd simplechat-aiohttp #5
  1. Chuyển tới thư mục làm việc
  2. Tạo virtualenv tên pyenv
  3. Active workspace pyenv
  4. Tạo một folder tên là simplechat-aiohttp
  5. Chuyển tới thư mục aiohttp vừa tạo

Các bạn chú ý, đoạn command trên có thể hơi khác trên máy các bạn, do mình dùng hđh archlinux, các bạn sử dụng distro fedora, debian thì bước 3 sẽ có hơi khác command một chút. Đối với các bạn window các bạn có thể vào thẳng ổ đĩa và tạo folder, sau đó tạo virtualenv.. (Mình sẽ viết bài hướng dẫn về cách tạo virtualenv cho tất cả os thông dụng sau bài này, và cập nhật link sau.)

Để xây dựng hệ thống chat với aiohttp, chúng ta cần cài đặt nhưng package sau:

pip install aiohttp
pip install aiohttp_session
pip install aiohttp-jinja2
pip install jinja2

và template cho trang login của chúng ta: Download here

Cấu hình aiohttp

Bây giờ chúng ta có đủ đồ chơi rồi, bắt tay vào phần setup aiohttp cơ bản thôi

Bạn hãy tạo thư mục theo ảnh như sau:

tạo thư mục cho simplechat

Tại thư mục root, bạn hãy tạo file server.py

import os
import jinja2
from aiohttp import web
import aiohttp_jinja2 as jtemplate
from routes import routes

PROJECT_APP_PATH = os.path.dirname(os.path.abspath(__file__)) #1
TEMPLATE_PATH = os.path.join(PROJECT_APP_PATH, "templates") #2
STATIC_PATH = os.path.join(PROJECT_APP_PATH, "static") #3
MEDIA_PATH = os.path.join(PROJECT_APP_PATH, "media") #4

app = web.Application() #5
app.add_routes(routes) #6
app.router.add_static('/static', STATIC_PATH, name='static') #7
app.router.add_static('/media', MEDIA_PATH, name='media') #8
jtemplate.setup(app, loader=jinja2.FileSystemLoader(TEMPLATE_PATH)) #9


if __name__ == '__main__':
    web.run_app(app) #10

Từ dòng 1 tới dòng 6 là các thư viện cần thiết cho chúng setup aiohttp hoạt động được

  1. Khai báo đường dẫn đến thư mục của simplechat-aiohttp
  2. Khai báo đường dẫn đến thư mục templates
  3. Khai báo đường dẫn đến thư mục static
  4. Khai báo đường dẫn đến thư mục media
  5. Khai báo class Application(), tất cả các aiohttp server đều được điều khiển bởi aiohttp.web.Application . Application() được dùng để đăng ký startup/cleanup các signal, kết nối các route
  6. Thêm routes từ module routes. add_route() là method cho phép bạn thêm các đường dẫn như trang chủ, login, logout
  7. add_static() cũng như add_routes() nhưng khác là add_static cho phép bạn tạo url, và trỏ vào thư mục được chỉ định để sử dụng các tài nguyên. Trong bài này, /staticđược dẫn vào thư mục chứa fonts, css, images, js...
  8. Tương tự như /static, mình dùng add_static() để tạo một url dẫn vào thư mục chứa hình ảnh
  9. jtemplate.setup() nhận vào 2 tham số: app và loader. Tham số loader sẽ dẫn tới thư mục chứa templates của simplechat-aiohttp
  10. Đây là dòng quan trọng để khởi chạy server cho chúng ta.

Tiếp đến, vẫn ở thư mục root của simplechat-aiohttp, chúng ta tạo tiếp file routes.py

from aiohttp import web
from chat.views import Login #1

routes = [
    web.get('/', Login, name="homepage") #2
]
  1. import Login từ module chat
  2. Hiện tại chúng ta chỉ tạo một trang chủ. Method web.get() mặc định sẽ cho chúng ta dùng method GET cho phép HEAD request trả về response của header. Bạn có thể xem chi tiết tại đây

Trong thư mục chat, bạn tạo 2 file __init__.py, views.py. Với các bạn sử dụng Pycharm, các bạn có thể tạo thư mục chat này có sẵn file __init__.py bằng cách click phải vào simplechat-aiohttp (được tô xanh trong hình) > New > Python Package > nhập chat và enter. File __init__.py giúp python biết đây không phải thư mục bình thường mà là một module. Với các bạn tạo bằng tay thì file __init__.py này rỗng, không có nội dung

folder chat

views.py

from aiohttp import web
import aiohttp_jinja2

class Login(web.View): #1
    @aiohttp_jinja2.template('chat/room.html')#2
    async def get(self): #3
        return {'content': 'Welcome'} #4
  1. Ta tạo một class Login kế thừa class abstract web.View
  2. Chỉ định template cho trang login
  3. Khi một function được khai báo như async def có nghĩa rằng method này là một coroutine1 , và công tắc đề bẫy async def là await. awaitnói cho dễ hiểu có nghĩa là "Ê, nếu ông rảnh thì đi làm việc khác trong khi tôi chờ cái này chạy xong đi. Khi nào cái này xong thì quay lại đây làm tiếp.". Mình sẽ làm một series về asyncio giúp các bản hiểu rõ hơn về vấn đề này sau.
  4. Trả về context để sử dụng trong template

Bây giờ bạn hãy tạo các file và thư mục cho thư mục templates như hình sau:

folder templates

base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}Đây là nội dung sẽ bị ghi đè{% endblock %} | Simplechat - Tự học Python</title> {#1#}
</head>
<body>
{% block body_content %} {#2#}
Đây là nội dung sẽ bị ghi đè
{% endblock %}
</body>
</html>
  1. Đây là ngôn ngữ của jinja2, các bạn có thể tham khảo thêm tại đây. Nội dung trong {% block title}{% endblock %} sẽ được ghi đè bởi những template con.
  2. Tương tự như trên, nội dung của {% block content}{% endblock %} trong template con sẽ xuất hiện ở đây.

room.html

{% extends "base.html" %} {#1#}

{% block title %}Đăng nhập vào room chat{% endblock %} {#2#}

{% block body_content %} {#3#}
    {{ content }} {#4#}
{% endblock %}
  1. Đây là simple tag khai báo rằng room.html là con của base.html. Cho phép room.html ghi đè các block có trong base.html
  2. Ghi đè nội dung block title ở base.html
  3. Ghi đè nội dung block body_content ở base.html
  4. Hiện context chúng ta đã assign ở homepage trong chat/views.php

Nếu template con không ghi đè các block ở template cha, thì nội dụng ở template cha sẽ hiển thị như giá trị mặc định.

Bây giờ chúng ta sẽ xem thử kết quả xem site chúng ta chạy có ổn không hay bị lỗi gì nha.

(pyenv)user@server simplechat-aiohttp: python server.py
======== Running on http://0.0.0.0:8080 ========
(Press CTRL+C to quit)

Nếu các bạn chạy command và hiện ra output như trên thì các bạn đã thành công rồi đó.

kết quả aiohttp bước đầu

Bài tiếp theo chúng ta sẽ đưa giao diện của trang html login v1 mà bạn đã download về và tiếp tục hoàn thiện chương trình chat của chúng ta. Mọi ý kiến góp ý của các bạn mình rất hoan nghênh. Các bạn thắc mắc có thể hỏi mình bằng cách comment tại bài viết này hoặc trên group Python Community Viet Nam. Chúc bạn học lập trình Python thành công

Các thẻ
Bài viết liên quan
2 nhận xét
  1. Trả lời

    hieu

    29 Tháng 10, 2018

    anh có thể hướng dẫn bước activate workspace trên window khong a
    em khong the chay duoc project

Nhận xét mới

bắt buộc

yu.kusanagi
Từ Anh Vũ
Hồ Chí Minh, Việt Nam

Xin chào, tôi tên Từ Anh Vũ và là 1 free lancer developer và ngôn ngữ code yêu thích của tôi là Python và PHP. Công việc chủ yếu là viết các module cho magento, magento2, wordpress, django, flask và các framework khác
Nếu bạn muốn trao đổi với tôi hoặc muốn thuê tôi làm việc cho dự án của bạn, hãy liên hệ với tôi

ĐĂNG KÝ NHẬN BÀI MỚI

Tweets gần đây
Tác giả
Feeds
RSS / Atom
ADVERTISING

Đăng ký nhận bài viết mới tại hocpython.com?

Hãy đăng ký nhận bài viết mới tại hocpython.com để:

  • Không bỏ lỡ các bài tutorials mới tại hocpython.com!
  • Cập nhật các công nghệ mới trong python!

Chỉ cần điền email và họ tên của bạn và nhấn Đăng ký nhận tin!