Browser and Server Sync (Polling, Comet, Long Polling, WebSocket)

文章发表于4265天前。日期过于久远,请合理参考。
This article was created at 4265 days ago. It is too long, so please pay more attention.

1 前言#

这只是一篇简单介绍浏览器与服务器之间的实时数据交换的方法。 在客户端使用的是 coffeescript ,接触下来感觉这种语法还是不错的, 然后在学习的过程中,貌似coffeescript借鉴了许多 Ruby 的语法, 所以接下来我准备去看看Ruby,当然这个是题外话啦。 一旦接受了coffeescript这种设定,还是很带感的。

然后服务器用的是 pythonFlask 这一WEB框架以及 nodejs

主要参考的是:Browser 與 Server 持續同步的作法介紹 (Polling, Comet, Long Polling, WebSocket)

2 环境的搭建#

2.1 Flask#

  1. Install 安装步骤,请移步 这里 ,这里是官方的安装方式,在这里我接触到了python的虚拟环境。 感觉用这个virtualenv的确不错,然后我找到了一篇介绍这种的文章:virtualenv
  2. Quick Start 请移步这里 。我也是跟着快速教程一步一步做的,写出来的服务器也很简单。 毕竟这篇文章的主题不是这个。

2.2 Nodejs#

关于如何安装 nodejs 以及如何使用我在此不多累述。官方文档写的很详细。 然后我使用的是 expressjs 这一WEB框架。安装方式和快速入门点击 QuickStart

在这里着重写一下使用 coffeescript 来写nodejs的代码。 具体可以看这篇文章:My Node.js Express + CoffeeScript setup

我的做法只是用来其中的一条命令:

$ sudo npm install -g js2coffee

将express生成的app.js转成了app.coffee,然后将 package.json 中的

"start": "node app.js"

变成了:

"start": "coffee app.coffee"

具体的在我上面提到文章中有详细介绍。当然还可以看看这个:Express-coffee

3 Polling#

这是轮询的方式,是一种很常见的解决方案。然后我这里没有写代码。 思路就是使用setInterval()函数,定时访问服务器。构成一个一个polling.

4 Comet#

等待填坑……

5 Long Polling#

长轮询方式。 代码:

Post =
getId: ->
$.ajax {
type: 'POST'
url: '/getId'
context: $('body')
success: (data) ->
successHandle(data)
return
error: (xhr, type) ->
console.log xhr, type
return
}
return
# Success Handle
successHandle = (data) ->
console.log data.u_id
$('#show').append(data.u_id)
Post.getId()
return
# after loading run the below codes
$ ->
Post.getId()
return
from flask import Flask, session, redirect, url_for, escape, request, render_template, jsonify
import os
import random
import time
# app = Flask(__name__)
app = Flask(__name__,
# static_path='/static',
static_folder='static',
template_folder='templates')
@app.route('/')
def index():
if 'username' in session:
return render_template('logged.html',
number = random.random(),
username = escape(session['username']),)
return render_template('index.html')
@app.route('/login', methods=['GET', 'POST'])
def login():
"""
"""
if request.method == 'POST':
session['username'] = request.form['username']
return redirect(url_for('index'))
return render_template('login.html')
@app.route('/logout')
def logout():
# remove the username from the session if it's there
session.pop('username', None)
return redirect(url_for('index'))
# set the secret key. keep this really secret:
app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
@app.route('/getId', methods=['GET', 'POST'])
def getId():
while True:
time.sleep(3)
msg = jsonify(u_id = '100')
return msg
# with app.app_context():
# url_for('static', filename='zepto.min.js')
if __name__ == '__main__':
app.debug = True
app.run()

6 WebSocket#

等待填坑……

7 Socket.IO#

Socket.IO 这个我个人感觉不错,支持的浏览器也很多,然后使用的是nodejs。 有空的时候看看源代码,看看究竟是如何实现的。

然后下面的代码都是按照官方的步骤做的,只是稍微修改了一下。具体的可以参照 这里

代码:

extends layout
block content
h1= title
p Welcome to #{title}
view raw index.jade hosted with ❤ by GitHub
doctype 5
html
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
script(src="/socket.io/socket.io.js")
script(src="/javascripts/zepto.min.js")
script(src="/javascripts/app.js")
body
block content
view raw layout.jade hosted with ❤ by GitHub
# $show = document.getElementById('show')
show = (data) ->
$show = $('body')
console.log $show
msg = data.hello || data.id
$show.append "<p>#{msg}</p>"
return
socket = io.connect 'http://localhost:3000'
socket.on 'news', (data) ->
console.log data
show data
socket.emit 'my other event', {my: 'data'}
return
socket.on 'random', (data) ->
show data
return
###
Module dependencies.
###
express = require("express")
socket_io = require("socket.io")
routes = require("./routes")
user = require("./routes/user")
http = require("http")
path = require("path")
app = express()
app.configure ->
app.set "port", process.env.PORT or 3000
app.set "views", __dirname + "/views"
app.set "view engine", "jade"
app.use express.favicon()
app.use express.logger("dev")
app.use express.bodyParser()
app.use express.methodOverride()
app.use app.router
app.use express.static(path.join(__dirname, "public"))
app.configure "development", ->
app.use express.errorHandler()
app.get "/", routes.index
app.get "/users", user.list
server = http.createServer(app)
server.listen app.get("port"), ->
console.log "Express server listening on port " + app.get("port")
io = socket_io.listen server
io.sockets.on 'connection', (socket) ->
socket.emit 'news', {hello: 'world'}
setInterval ->
socket.emit 'random', { id: Math.random() }
return
, 1000
socket.on 'my other event', (data) ->
console.log(data)
return
return

8 后记#

然后接下来需要思考的是数据库更新,如何通知web服务器发送更新数据? 继续等待填坑……

pollingcommetlong-pollingwebsocketnodejsjavascriptcoffeescriptpython

Junjia Ni#

Email: creamidea@gmail.com

Date: 2013-07-30

LMT: 2016-11-10 Thu 12:43


Load Comments

Junjia Ni

2013-07-30

2016-11-10 Thu 13:03

Emacs 25.1.1 (Org mode 9.0)

2016-11-10 Thu 12:43