R语言构建websocket服务器

R的极客理想系列文章,涵盖了R的思想,使用,工具,创新等的一系列要点,以我个人的学习和体验去诠释R的强大。

R语言作为统计学一门语言,一直在小众领域闪耀着光芒。直到大数据的爆发,R语言变成了一门炙手可热的数据分析的利器。随着越来越多的工程背景的人的加入,R语言的社区在迅速扩大成长。现在已不仅仅是统计领域,教育,银行,电商,互联网….都在使用R语言。

要成为有理想的极客,我们不能停留在语法上,要掌握牢固的数学,概率,统计知识,同时还要有创新精神,把R语言发挥到各个领域。让我们一起动起来吧,开始R的极客理想。

关于作者:

  • 张丹(Conan), 程序员Java,R,PHP,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/r-websocket-websockets/

websockets-r

前言

R语言从一门统计语言,正向着工业化语言发展。不仅支持web的可视化,web的基本操作,还支持websocket。我们的互联网应用程序不用再绕道Rserve,直接通过websocket协议,就能实现与R语言的交互。

R语言正在发生着技术革命,更先进,更便捷….

目录

  1. websockets介绍
  2. websockets安装
  3. websockets的API介绍
  4. 快速启动websockets服务器demo
  5. R语言创建websocket服务器实例
  6. R语言创建websocket客户端连接
  7. 用浏览器HTML5原生API客户端连接

1. websockets介绍

Websocket协议是基于HTML5规范的,在浏览器上实现的客户端和服务器端通信协议。

Websocket有以下优势:

  • 显着降低网络开销。
  • 减少服务器的处理开销。
  • 简化Web客户端(推)的快速异步更新。
  • 简化服务器和客户端之间的耦合状态。

websockets包,是R语言的一个websocket接口的类库。通过websockets包,可以非常简单地使用R语言构建一个websocket服务器实例。同时,websockets包还提供客户端的API。

websockets包的发布页:http://cran.r-project.org/web/packages/websockets/index.html

2. websockets安装

系统环境:

  • Linux: Ubuntu Server 12.04.2 LTS 64bit
  • R: 3.0.1 x86_64-pc-linux-gnu
  • RStudio Server online

注:经过测试websockets在win环境中,有各种的问题。请使用linux环境。

websockets安装,加载


~ R

> install.packages("websockets")
also installing the dependency ‘caTools’

trying URL 'http://mirror.bjtu.edu.cn/cran/bin/windows/contrib/3.0/caTools_1.16.zip'
Content type 'application/zip' length 227507 bytes (222 Kb)
opened URL
downloaded 222 Kb

trying URL 'http://mirror.bjtu.edu.cn/cran/bin/windows/contrib/3.0/websockets_1.1.7.zip'
Content type 'application/zip' length 272593 bytes (266 Kb)
opened URL
downloaded 266 Kb

package ‘caTools’ successfully unpacked and MD5 sums checked
package ‘websockets’ successfully unpacked and MD5 sums checked

> library(websockets)
'websockets'R3.0.2

websockets库依赖于caTools库,caTools是一个工具集,请参考文章:caTools一个奇特的工具集

补充:websockets包被移出CRAN。

websockets包在2014-03-02时,被移出了CRAN包,目前还不知道是什么原因。

原文网页地址 http://cran.r-project.org/web/packages/websockets/index.html


Package ‘websockets’ was removed from the CRAN repository.

Formerly available versions can be obtained from the archive.

Archived on 2014-03-02 at the request of the maintainer.

这样我们在安装websockets包的时候,通过install.packages()的命令就会出错误了。


> install.packages("websockets")
Installing package into ‘/home/conan/R/x86_64-pc-linux-gnu-library/3.0’
(as ‘lib’ is unspecified)
警告信息:
package ‘websockets’ is not available (for R version 3.0.1)

我们需要下载安装包,手动进行安装。


# 下载最新的websockets包
~ wget http://cran.r-project.org/src/contrib/Archive/websockets/websockets_1.1.7.tar.gz

# 在当前目录安装websockets
~  R CMD INSTALL websockets_1.1.7.tar.gz
* installing to library ‘/home/conan/R/x86_64-pc-linux-gnu-library/3.0’
ERROR: dependencies ‘caTools’, ‘digest’ are not available for package ‘websockets’
* removing ‘/home/conan/R/x86_64-pc-linux-gnu-library/3.0/websockets’

安装过程中出现错误,提示为缺少依赖包caTools, digest,所以我们需要先安装这两个依赖包。


# 启动R程序
~ R

# 安装依赖包
> install.packages("caTools")
> install.packages("digest")

# 回到命令行,再次安装websockets包,安装成功
~ R CMD INSTALL websockets_1.1.7.tar.gz
* installing to library ‘/home/conan/R/x86_64-pc-linux-gnu-library/3.0’
* installing *source* package ‘websockets’ ...
** 成功将‘websockets’程序包解包并MD5和检查
** libs
gcc -std=gnu99 -I/usr/share/R/include -DNDEBUG     -DLWS_NO_FORK -fpic  -O3 -pipe  -g  -c libsock.c -o libsock.o
gcc -std=gnu99 -shared -o websockets.so libsock.o -L/usr/lib/R/lib -lR
installing to /home/conan/R/x86_64-pc-linux-gnu-library/3.0/websockets/libs
** R
** demo
** inst
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** installing vignettes
   ‘websockets.Rnw’
** testing if installed package can be loaded
* DONE (websockets)

# 启动R程序
~ R

# 加载websockets包
> library(websockets)

通过手动的方式,我们就安装好了websockets包。

3. websockets的API介绍

  • create_server: 创建一个websocket服务器实例,并绑定端口
  • daemonize: 绑定websocket服务器实例守护进程,到R的控制台,不支持Windows
  • http_response: 发送HTTP Response请求到socket
  • http_vars: 解析HTTP GET/POST参数列表
  • service: 注册websocket实例的服务队列
  • set_callback: 在websocket实例中,定义R函数
  • static_file_service: 静态文件
  • static_text_service: 静态文本
  • websocket: 创建一个websocket客户端实例
  • websocket_broadcast: 向注册在同一个websocket服务器实例的客户端发广播
  • websocket_close: 关闭客户端连接
  • websocket_write: 通过websocket进行数据传输

4. 快速启动websockets服务器demo

websockets包,提供了一个demo。通过demo(websockets)函数,直接启动一个简单的websocket服务器。


~ R

> library(websockets)
'websockets'R3.0.2

> demo(websockets)

        demo(websockets)
        ---- ~~~~~~~~~~

Type     to start :

> # Simple example
> require(websockets)

> w = create_server()

> f = function(DATA, WS, ...)
+ {
+   cat("Receive callback\n")
+   D = ""
+   if(is.raw(DATA)) D = rawToChar(DATA)
+   websocket_write(DATA=paste("You sent",D,"\n",collapse=" "),WS=WS)
+ }

> set_callback('receive',f,w)

> cl = function(WS)
+ {
+   cat("Websocket client socket ",WS$socket," has closed.\n")
+ }

> set_callback('closed',cl,w)

> es = function(WS)
+ {
+   cat("Websocket client socket ",WS$socket," has been established.\n")
+ }

> set_callback('established',es,w)

> cat("Direct your web browser to http://localhost:7681\n")
Direct your web browser to http://localhost:7681

> while(TRUE) service(w)

打开浏览器:http://192.168.1.201:7681

websockets-demo

服务器日志:


Websocket client socket  20  has closed.
Websocket client socket  8  has been established.
Websocket client socket  21  has closed.

查看服务器端:


~ netstat -nltp|grep r

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:7681            0.0.0.0:*               LISTEN      2231/rsession

5. R语言创建websocket服务器实例

  • 1. 加载类库
  • 2. 初始化create_server()
  • 3. 定义回调函数
  • 4. 定义事件服务

~ R

#加载类库
library(websockets)

#浏览器的HTTP输出
text = "<html><body>
<h1>Hello world</h1>
</body></html>"

## 创建服务实例
w = create_server(port=7681,webpage=static_text_service(text))

## 监听receive
recv = function(DATA, WS, ...){
  cat("Receive callback\n")
  D = ""
  if(is.raw(DATA)){D = rawToChar(DATA)}

  cat("Callback:You sent",D,"\n")
  websocket_write(DATA=paste("You sent",D,"\n",collapse=" "),WS=WS)
}
set_callback('receive',recv,w)

## 监听closed
cl = function(WS){
  cat("Websocket client socket ",WS$socket," has closed.\n")
}
set_callback('closed',cl,w)

## established
es = function(WS){
  cat("Websocket client socket ",WS$socket," has been established.\n")
}
set_callback('established',es,w)

#对所有的连接进行监听
while(TRUE) service(w)

6. R语言创建websocket客户端连接

在Linux环境中,新建一个文件:client.r


~ vi client.r

#加载类库
library(websockets)

#创建客户端实例
client = websocket("ws://192.168.1.201",port=7681)

#监听receive
rece<-function(DATA, WS, HEADER) {   D=''   if(is.raw(DATA)){     cat("raw data")     D = rawToChar(DATA)   }   cat("==>",D,"\n")
}
set_callback("receive",rece, client)

#向服务器发请求
websocket_write("2222", client)

#输出服务器的返回值
service(client)

#关闭连接
websocket_close(client)

运行程序:


> library(websockets)
>
> client = websocket("ws://192.168.1.201",port=7681)
>
> # receive
> rece<-function(DATA, WS, HEADER) { +   D='' +   if(is.raw(DATA)){ +     cat("raw data") +     D = rawToChar(DATA) +   } +   cat("==>",D,"\n")
+ }
> set_callback("receive",rece, client)
> websocket_write("2222", client)
[1] 1
>
> service(client)
raw data==> You sent 2222

>
> websocket_close(client)
Client socket 3  was closed.

7. 用浏览器HTML5原生API客户端连接

打开浏览器:http://192.168.1.201:7681/

websockets-html5-js

我们可以通过浏览器console写js的代码,实现和websocket服务器的通信。

原生的HTML5程序


var ws = new WebSocket("ws://192.168.1.201:7681");
ws.onopen = function(){
console.log("connecting");
};
ws.onmessage = function(message){
console.log(message.data);
console.log(message);
};
function postToServer(msg){
ws.send(msg);
}
function closeConnect(){
ws.close();
console.log("closed");
}

postToServer('browser');
closeConnect();

我们这样就完成了,R语言构建的websocket服务器测试。又给R语言与其他语言通信打开了一条便利的通道。

关于websocket的其他语言实现,请参考文章:

转载请注明出处:
http://blog.fens.me/r-websocket-websockets/

打赏作者

This entry was posted in R语言实践

0 0 votes
Article Rating
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

8 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Xuesong

基于R WebSocket是否可以构建HTML5的实时曲线图表,能否给出实例讲解呢?

Conan Zhang

等有时间吧,最近太忙了。

ypchen

Package ‘websockets’ was removed from the CRAN repository.

Formerly available versions can be obtained from the
archive.

Archived on 2014-03-02 at the request of the maintainer.

——————————

太不幸了吧

Conan Zhang

这种问题就搞的比较麻烦,不知道什么原因。看来文章还要再修改一下,再写一下通过archive安装。

对了,R语言会议报个名!讲小明说的那个,我用提交什么材料吗?

ypchen

也不知道为什么cran不给托管了 以后是不更新了 还是说作者自己放别的地方了

提交标题和摘要就行了 然后发一封邮件给组委会

Conan Zhang

文章已更新,增加通过archive来安装!

obarisk

好像改成httpuv了,參考這個https://github.com/rstudio/R-Websockets

Conan Zhang

可以是这样的,加入RStudio希望这个包能更好用。

8
0
Would love your thoughts, please comment.x
()
x