最近花了一些时间,看了一下OpenResty的东西,感觉用来做API网关的确很赞:
https://github.com/neohope/NeoDemosOpenResty
官网:
https://openresty.org/cn/
Learn and share.
最近花了一些时间,看了一下OpenResty的东西,感觉用来做API网关的确很赞:
https://github.com/neohope/NeoDemosOpenResty
官网:
https://openresty.org/cn/
本节说明一下遗留的一些内容:
1、开启GPU加速
如果需要GPU加速,除了Intel指定的硬件外,还需要:
https://software.intel.com/en-us/intel-media-server-studio
有社区版,大家感兴趣的可以自己试一下。
2、开启VCA加速
如果需要支持VCA(Intel Visual Compute Accelerator)卡加速,请参考
https://software.intel.com/en-us/webrtc-conference-server-guide-mcu-installation#section2_3_10
3、支持集群
如果需要支持集群,请参考
https://software.intel.com/en-us/webrtc-conference-server-guide-mcu-installation#section2_3_8
咋说呢,总体上感觉这个集群方案有些过于复杂,需要用的时候再看吧。
本节运行一下WebRTC自带的两个Demo。
大家可以解压CS_WebRTC_Client_SDK_JavaScript.v4.1,看一下,里面有两个Demo。
第一个Demo是conference,已经集成到MCU Server里面了,当我们运行bin/start-all.sh命令时,就会启动了。
我们可以通过Chrome访问https://172.16.172.80:3004,就可以看到自己的视频。
再打开一个Chrome访问https://172.16.172.80:3004,就可以看到两路视频合并为一路视频输出了。
由于https证书为自签名,所以浏览器会给出安全提示,将证书加入可信范围,跳过就好了,全部功能只在Chrome成功过。
本节重点看下第二个Demo,是P2P。这个Demo需要两个服务的支持,一个是在第一节我们安装的Peer Server,另一个是需要安装一个turnserver。
1、下载coturn
https://github.com/coturn/coturn/releases
2、安装依赖库
2.1、安装levent
https://sourceforge.net/projects/levent/files/release-2.0.22-stable/
./configure make make install
2.2、安装openssl-devel
sudo yum install openssl openssl-libs openssl-devel
2.3、安装
yum install sqlite-devel
3、编译coturn
./configure make
4、编写coturn配置文件
vi path_to_coturn/bin/urnserver.conf #新增以下内容 listening-device=enp0s3 listening-port=3478 relay-device=enp0s3 min-port=59000 max-port=65000 fingerprint lt-cred-mech use-auth-secret static-auth-secret=demo realm=demo stale-nonce user=demo:demo cert=path_to_coturn/examples/etc/turn_server_cert.pem pkey=path_to_coturn/examples/etc/turn_server_pkey.pem no-loopback-peers no-multicast-peers mobility no-cli
5、启动coturn
cd path_to_coturn/bin sudo ./turnserver
6、启动PeerServer
cd PeerServer-Release-4.1 node peerserver.js
7、编辑本地页面peercall.html的以下部分
var serverAddress='https://172.16.172.80:8096';
const signaling = new SignalingChannel();
let publicationForCamera;
let publicationForScreen;
var p2p = new Ics.P2P.P2PClient({
audioEncodings: true,
videoEncodings: [{codec:{name: 'h264'}}, {codec: {name: 'vp9'}}, {codec: {name: 'vp8'}}],
rtcConfiguration:{
iceServers: [{
urls: "stun:172.16.172.80:3478"
}, {
urls: ["turn:172.16.172.80:3478?transport=udp",
"turn:172.16.172.80:3478?transport=tcp"
],
credential: "demo",
username: "demo"
}]
},
}, signaling);
8、测试
现在用两个Chrome页面浏览本地页面peercall.html,也能使用部分功能,但如果使用全部功能,还是要部署到HTTP服务器的。
9、为了支持Chrome分享桌面,需要安装并配置插件
9.1、修改插件中域名配置
CS_WebRTC_Client_SDK_JavaScript.v4.1\screen-sharing-chrome-extension\manifest.json
"externally_connectable": {
"matches": ["*://172.16.172.80/*", "*://localhost/*"]
},
9.2、打开扩展管理
Chrome->Settings->Entensions
9.3、开启Developer mode
9.4、Load unpacked
选择CS_WebRTC_Client_SDK_JavaScript.v4.1\screen-sharing-chrome-extension
9.5、安装后,会有一个插件ID
我的插件ID为:ongdcdianlnmjiegeandlohjbogjndmc
10、编辑本地页面peercall.html的以下部分
extensionId:'ongdcdianlnmjiegeandlohjbogjndmc'
11、部署网站
将页面部署到你熟悉的HTTP服务器,加入HTTPS证书,并要在HTTP头中允许CORS。
'Access-Control-Allow-Origin', '*'
一个偷懒的办法是,将MCU-Release-v4.1/extras/basic_example复制一份,按规则替换了静态资源。
修改下面几个文件;
package.json修改包描述 quickfix2spdybug47.js删除 samplertcservice.js删除不需要的API,然后修改端口为HTTP4001、HTTPS4004
然后启动了网站。
node samplertcservice.js
12、测试
这样访问https://172.16.172.80:4004即可。
第一个页面,Login左边填写User01,点击登录
第二个页面,Login左边填写User02,点击登录
第一个页面,SetRemoteId为User02
第二个页面,SetRemoteId为User01
第一个页面,SendData数据“123”,第二个页面可以看到。
第一个页面,Share Camera/Share Screen,第二个页面可以看到。
PS:
如果看不到,建议检查以下几件事情
A、必须HTTPS访问
B、Chrom和FF的控制台是否有报错
C、是否证书和HTTPS网站加入了可信列表
D、是否证书和HTTPS的地址是一致的
PS:
如果是Chrome插件有问题,主要确认
A、必须是HTTPS访问
B、网页的Chrome插件ID,与Chrome中插件ID是否一致
C、插件配置中的通配域名,是否与你的域名一致
D、是否证书和HTTPS网站加入了可信列表
E、是否证书和HTTPS的地址是一致的
F、是否打开了开发者模式
13、关闭页面
可以查看PeerServer的日志
本节开始安装MCU Server。
MCU Server有两种工作模式,一种是通过GPU,一种是通过CPU,由于我用的是虚拟机,所以这里用的是CPU。
MCU Server是自带自签名证书的域名与实际域名不匹配,所以大家要生成自己的证书。
1、权限配置
1.1、/etc/security/limits.conf
* hard nproc unlimited * soft nproc unlimited * hard nofile 163840 * soft nofile 163840 * hard stack 1024 * soft stack 1024
1.2、/etc/pam.d/login
session required pam_limits.so
1.3、/etc/security/limits.d/xx-nproc.conf
* hard nproc unlimited * soft nproc unlimited
1.4、/etc/sysctl.conf
fs.file-max=200000 net.core.rmem_max=16777216 net.core.wmem_max=16777216 net.core.rmem_default=16777216 net.core.wmem_default=16777216 net.ipv4.udp_mem=4096 87380 16777216 net.ipv4.tcp_rmem=4096 87380 16777216 net.ipv4.tcp_wmem=4096 65536 16777216 net.ipv4.tcp_mem=8388608 8388608 16777216
1.5、启用设置
sudo /sbin/sysctl -p ulimit -a
2、解压文件
tar -xf CS_WebRTC_Conference_Server_MCU.v4.1.tgz mv Release-v4.1 /neohope/webrtc/MCU-Release-v4.1
3、编译依赖库
3.1、Cisco OpenH264
cd /neohope/webrtc/MCU-Release-v4.1/video_agent #编译并安装依赖库 install_deps.sh #关闭支持 #uninstall_openh264.sh #开启支持 #install_openh264.sh
3.2、ffmpeg with libfdk_aac
cd /neohope/webrtc/MCU-Release-v4.1/audio_agent compile_ffmpeg_with_libfdkaac.sh mv ffmpeg_libfdkaac_lib/* lib/
4、初始化服务
4.1、生成证书
#生成RSA私钥 openssl genrsa -out ryans-key.pem 2048 Generating RSA private key, 2048 bit long modulus ..........................................................+++ ................................................................................ ........................................+++ e is 65537 (0x10001) #生成CSR(certificate signing request) openssl req -new -sha256 -key ryans-key.pem -out ryans-csr.pem You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [XX]:CN State or Province Name (full name) []:SH Locality Name (eg, city) [Default City]:SH Organization Name (eg, company) [Default Company Ltd]:NEOHOPE Organizational Unit Name (eg, section) []:RD Common Name (eg, your name or your server's hostname) []:172.16.172.80 Email Address []:NEOHOPE@YAHOO.COM Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: #生成自签名证书 openssl x509 -req -in ryans-csr.pem -signkey ryans-key.pem -out ryans-cert.pem Signature ok subject=/C=CN/ST=SH/L=SH/O=NEOHOPE/OU=RD/CN=172.16.172.80/emailAddress=NEOHOPE@Y AHOO.COM Getting Private key #转换为p12格式 #openssl pkcs12 -export -in ryans-cert.pem -inkey ryans-key.pem -certfile ca-cert.pem -out ryans.pfx openssl pkcs12 -export -in ryans-cert.pem -inkey ryans-key.pem -out ryans.pfx Enter Export Password: Verifying - Enter Export Password:
4.2、安装证书
cp ryans.pfx ../MCU-Release-v4.1/extras/basic_example/cert/certificate.pfx cp ryans.pfx ../MCU-Release-v4.1/portal/cert/certificate.pfx #cp ryans.pfx ../MCU-Release-v4.1/webrtc_agent/cert/certificate.pfx cp ryans.pfx ../MCU-Release-v4.1/management_console/cert/certificate.pfx #然后分别到basic_example、portal、management_console下面,执行 node initcert.js
5、初始化服务
#非GPU加速 bin/init-all.sh #GPU加速 #bin/init-all.sh --hardware
6、开启服务
bin/start-all.sh
starting nuve, stdout -> /home/neohope/webrtc/MCU-Release-v4.1/logs/woogeen-nuve.stdout
starting cluster-manager, stdout -> /home/neohope/webrtc/MCU-Release-v4.1/logs/woogeen-cluster-manager.stdout
starting audio-agent, stdout -> /home/neohope/webrtc/MCU-Release-v4.1/logs/woogeen-audio-agent.stdout
starting conference-agent, stdout -> /home/neohope/webrtc/MCU-Release-v4.1/logs/woogeen-conference-agent.stdout
2018-10-11 00:24:30.336 - INFO: AmqpClient - Connecting to rabbitMQ server OK, hostPort: { host: 'localhost', port: 5672 }
2018-10-11 00:24:30.366 - INFO: ErizoAgent - conference agent join cluster ok.
2018-10-11 00:24:30.415 - INFO: ClusterWorker - Join cluster woogeen-cluster OK.
2018-10-11 00:24:30.429 - INFO: ErizoAgent - as rpc server ok.
2018-10-11 00:24:30.431 - INFO: ErizoAgent - as monitoring target ok.
starting recording-agent, stdout -> /home/neohope/webrtc/MCU-Release-v4.1/logs/woogeen-recording-agent.stdout
2018-10-11 00:24:32.547 - INFO: AmqpClient - Connecting to rabbitMQ server OK, hostPort: { host: 'localhost', port: 5672 }
starting sip-agent, stdout -> /home/neohope/webrtc/MCU-Release-v4.1/logs/woogeen-sip-agent.stdout
2018-10-11 00:24:33.886 - INFO: AmqpClient - Connecting to rabbitMQ server OK, hostPort: { host: 'localhost', port: 5672 }
2018-10-11 00:24:33.914 - INFO: ErizoAgent - sip agent join cluster ok.
2018-10-11 00:24:33.961 - INFO: ClusterWorker - Join cluster woogeen-cluster OK.
2018-10-11 00:24:33.970 - INFO: ErizoAgent - as rpc server ok.
2018-10-11 00:24:33.973 - INFO: ErizoAgent - as monitoring target ok.
starting streaming-agent, stdout -> /home/neohope/webrtc/MCU-Release-v4.1/logs/woogeen-streaming-agent.stdout
2018-10-11 00:24:35.160 - INFO: AmqpClient - Connecting to rabbitMQ server OK, hostPort: { host: 'localhost', port: 5672 }
2018-10-11 00:24:35.187 - INFO: ErizoAgent - streaming agent join cluster ok.
2018-10-11 00:24:35.235 - INFO: ClusterWorker - Join cluster woogeen-cluster OK.
2018-10-11 00:24:35.246 - INFO: ErizoAgent - as rpc server ok.
2018-10-11 00:24:35.262 - INFO: ErizoAgent - as monitoring target ok.
starting video-agent, stdout -> /home/neohope/webrtc/MCU-Release-v4.1/logs/woogeen-video-agent.stdout
2018-10-11 00:24:36.529 - INFO: AmqpClient - Connecting to rabbitMQ server OK, hostPort: { host: 'localhost', port: 5672 }
2018-10-11 00:24:36.563 - INFO: ErizoAgent - video agent join cluster ok.
2018-10-11 00:24:36.603 - INFO: ClusterWorker - Join cluster woogeen-cluster OK.
2018-10-11 00:24:36.616 - INFO: ErizoAgent - as rpc server ok.
2018-10-11 00:24:36.631 - INFO: ErizoAgent - as monitoring target ok.
starting webrtc-agent, stdout -> /home/neohope/webrtc/MCU-Release-v4.1/logs/woogeen-webrtc-agent.stdout
2018-10-11 00:24:37.938 - INFO: AmqpClient - Connecting to rabbitMQ server OK, hostPort: { host: 'localhost', port: 5672 }
2018-10-11 00:24:37.964 - INFO: ErizoAgent - webrtc agent join cluster ok.
2018-10-11 00:24:37.999 - INFO: ClusterWorker - Join cluster woogeen-cluster OK.
2018-10-11 00:24:38.020 - INFO: ErizoAgent - as rpc server ok.
2018-10-11 00:24:38.024 - INFO: ErizoAgent - as monitoring target ok.
starting management-console, stdout -> /home/neohope/webrtc/MCU-Release-v4.1/logs/woogeen-management-console.stdout
Start management-console HTTP server
starting portal, stdout -> /home/neohope/webrtc/MCU-Release-v4.1/logs/woogeen-portal.stdout
2018-10-11 00:24:40.691 - INFO: AmqpClient - Connecting to rabbitMQ server OK, hostPort: { host: 'localhost', port: 5672 }
2018-10-11 00:24:40.715 - INFO: Main - portal initializing as rpc client ok
2018-10-11 00:24:40.733 - INFO: Main - portal join cluster ok, with rpcID: portal-089f86b5d0a4c156d6b5@172.16.172.80
2018-10-11 00:24:40.734 - INFO: ClusterWorker - Join cluster woogeen-cluster OK.
2018-10-11 00:24:40.741 - INFO: Main - portal initializing as rpc server ok
2018-10-11 00:24:40.748 - INFO: Main - portal-089f86b5d0a4c156d6b5@172.16.172.80 as monitor ready
starting sip-portal, stdout -> /home/neohope/webrtc/MCU-Release-v4.1/logs/woogeen-sip-portal.stdout
starting app, stdout -> /home/neohope/webrtc/MCU-Release-v4.1/logs/woogeen-app.stdout
7、测试服务,访问地址
7.1、你可以用浏览器浏览这个页面,可以看到自己的输入和输出视频画面
https://172.16.172.80:3004/
7.2、你可以用多个浏览器浏览这个页面,可以看到多路视频被合并为一个视频画面了。
https://172.16.172.80:3004/
7.3、如果不想合并多路视频,而是直接获取单个视频,可以用这个链接
https://172.16.172.80:3004/?forward=true
7.4、你可以用这个URL加入某个视频会议的房间
https://172.16.172.80:3004/?room=root_id
房间ID,在启动时,会输出到命令行及日志。
7.5、可以进入管理页面
https://172.16.172.80:3300/console/
需要输入Service_ID及Service_KEY。
可以在MCU-Release-v4.1/extras/basic_example/samplertcservice.js,查找这行代码即可得到:
icsREST.API.init('_service_ID_', '_service_KEY_', 'http://localhost:3000/', true);
8、停止服务
bin/stop-all.sh stopping nuve stopping cluster-manager stopping audio-agent stopping conference-agent stopping recording-agent stopping sip-agent stopping streaming-agent stopping video-agent stopping webrtc-agent stopping management-console stopping portal. stopping sip-portal stopping app
本系列主要是描述了,在虚拟机中通过CentOS7+Intel Collaboration Suite4.1实现WebRTC视频的基本步骤。
1、安装CentOS7,并配置网络信息
A、通过网卡1(HostOnly),实现主机与虚拟机的通讯
B、通过网卡2(NAT),实现虚拟机的外网访问
2、下载Intel Collaboration Suite4.1,并解压,将需要的组件上传到虚拟机
https://software.intel.com/en-us/webrtc-sdk
3、安装中间件
3.1、Node.js
https://nodejs.org/dist/8.12.0/
#官方文档上要的版本为node-v6.9.5-linux-x64,但实际要求v8以上 tar -xf node-v8.12.0-linux-x64.tar.gz mv node-v8.12.0-linux-x64 /home/neohope/ ln -s /home/neohope/webrtc/node-v8.12.0-linux-x64/bin/node /usr/bin/node ln -s /home/neohope/webrtc/node-v8.12.0-linux-x64/bin/npm /usr/bin/npm
3.2、Erlang
https://bintray.com/rabbitmq/rpm/erlang/19.3.6.11-2
#前两步骤主要是为了偷懒,安装依赖包 yum install erlang yum erase erlang-erts rpm -ivh erlang-19.3.6.11-2.el7.centos.x86_64.rpm
3.3、Rabbitmq
http://www.rabbitmq.com/download.html
#注意Erlang版本依赖 rpm -ivh erlang-19.3.6.11-2.el7.centos.x86_64.rpm #配置为自动启动 chkconfig rabbitmq-server on #开启服务 service rabbitmq-server start
3.4、MongoDB
http://downloads-distro.mongodb.org/repo/redhat/os/x86_64/RPMS/
#官方要的mongodb版本很低 rpm -ivh mongo-10gen-2.4.9-mongodb_1.x86_64.rpm rpm -ivh mongo-10gen-server-2.4.9-mongodb_1.x86_64.rpm
4、安装Peer Server
4.1、安装
tar –zxvf CS_WebRTC_Conference_Server_Peer.v4.1.tgz mv PeerServer-Release-4.1 /home/neohope/ cd /home/neohope/PeerServer-Release-4.1 npm install
4.2、测试
cd /home/neohope/PeerServer-Release-4.1 node peerserver.js #测试完毕后ctrl+c退出
API之于程序员就如同图形界面之于普通用户(end-user)。API中的『P』实际上指的是『程序员』(Programmer),而不是『程序』(Program),强调的是API是给程序员使用的这一事实。
在第13期Qt季刊,Matthias 的关于API设计的文章中提出了观点:API应该极简(minimal)且完备(complete)、语义清晰简单(have clear and simple semantics)、符合直觉(be intuitive)、易于记忆(be easy to memorize)和引导API使用者写出可读代码(lead to readable code)。
1 极简
极简的API是指每个class的public成员尽可能少,public的class也尽可能少。这样的API更易理解、记忆、调试和变更。
2 完备
完备的API是指期望有的功能都包含了。这点会和保持API极简有些冲突。如果一个成员函数放在错误的类中,那么这个函数的潜在用户就会找不到,这也是违反完备性的。
3 语义清晰简单
就像其他的设计一样,我们应该遵守最少意外原则(the principle of least surprise)。好的API应该可以让常见的事完成的更简单,并有可以完成不常见的事的可能性,但是却不会关注于那些不常见的事。解决的是具体问题;当没有需求时不要过度通用化解决方案。
4 符合直觉
就像计算机里的其他事物一样,API应该符合直觉。对于什么是符合直觉的什么不符合,不同经验和背景的人会有不同的看法。API符合直觉的测试方法:经验不很丰富的用户不用阅读API文档就能搞懂API,而且程序员不用了解API就能看明白使用API的代码。
5 易于记忆
为使API易于记忆,API的命名约定应该具有一致性和精确性。使用易于识别的模式和概念,并且避免用缩写。
6 引导API使用者写出可读代码
代码只写一次,却要多次的阅读(还有调试和修改)。写出可读性好的代码有时候要花费更多的时间,但对于产品的整个生命周期来说是节省了时间的。
最后,要记住的是,不同的用户会使用API的不同部分。尽管简单使用单个Qt类的实例应该符合直觉,但如果是要继承一个类,让用户事先看好文档是个合理的要求。
转载自coolshell
随着需要管理服务的增多,如何编排服务,成了一个很迫切的问题。本文就介绍几种常见的微服务编排方式:
1、Orchestration
这种方式,和BPM、ESB的思想很相似,实现方案多是同步的。
首先要有一个流程控制服务,该服务接收请求,依照业务逻辑规则,依次调用各个微服务,并最终完成处理逻辑。
这种方法的好处是,流程控制服务时时刻刻都知道每一笔业务究竟进行到了什么地步,监控业务成了相对简单的事情。
这种方法的坏处是,流程控制服务很容易控制了太多的业务逻辑,耦合度过高,变得臃肿,而各个微服务退化为单纯的增删改查,容易失去自身价值。
为了便于理解,您可以把控制服务看作BPM、ESB引擎,微服务为BPM、ESB的各种组件。
2、Choreography
这种方式,可以看作一种消息驱动模式,或者说是订阅发布模式,实现方案多是异步的。
每笔业务到来后,各个监听改事件的服务,会主动获取消息,处理,并可以按需发布自己的消息。
这种方法的好处是,耦合度低,每个服务都可以各司其职。
这种方法的坏处是,业务流程是通过订阅的方式来体现的,很难直接监控每笔业务的处理,因此需要增加相应的监控系统,来保证业务顺畅进行。
为了便于理解,您可以把不同队列看作不同种类的消息,微服务看作消息处理函数。
3、API网关
API网关,可以看作一种简单的接口聚合/拆分的方式。
每笔业务到来后,先到达网关,网关调用各微服务,并最终聚合/拆分需反馈的结果。
这种方法的好处是,对外接口相对稳定,可以利用LAN的带宽,弥补因特网的不足。
这种方法的坏处是,只适合业务逻辑较为简单的场景,业务逻辑过于复杂时,网关接口耦合度及复杂度会急剧升高,变得臃肿。
其实就是一个适配网关,比如对于Web端,可以一个页面同时发起几十个请求,而对于移动端,最好是一个页面就几个请求
。而采用API网关,后面的微服务可以是相同的。
1、总体来说很简单,首先新建一个MVC框架的项目,模板选择WebAPI,这样就搞定80%了。
2、WebApiConfig.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
namespace UrlToPngWebAPI
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.EnableSystemDiagnosticsTracing();
}
}
}
3、RouteConfig.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace UrlToPngWebAPI
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
}
4、请求结构
Web2PNGRequest.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Newtonsoft.Json;
namespace UrlToPngWebAPI.Models
{
public class Web2PNGRequest
{
[JsonProperty]
public String WebURL { get; set; }
[JsonProperty]
public String HeaderPath { get; set; }
[JsonProperty]
public String FooterPath { get; set; }
}
}
5、返回结构
Web2PNGResponse.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Newtonsoft.Json;
namespace UrlToPngWebAPI.Models
{
public class Web2PNGResponse
{
[JsonProperty]
public int ErrorCode { get; set; }
[JsonProperty]
public String ErrorInfo { get; set; }
[JsonProperty]
public String PNGPath { get; set; }
}
}
6、Controller
Url2PNGController.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Web.Helpers;
using System.Web.Http;
using Newtonsoft.Json;
using UrlToPngCsTest;
using UrlToPngWebAPI.Models;
using UrlToPngWebAPI.Pulgins;
namespace UrlToPngWebAPI.Controllers
{
public class Url2PNGController : ApiController
{
// 返回输入参数示例
public HttpResponseMessage Get()
{
Web2PNGRequest req = new Web2PNGRequest();
req.WebURL = "webURL";
req.HeaderPath = "headerPath";
req.FooterPath = "footerPath";
String jsonString = JsonConvert.SerializeObject(req);
HttpResponseMessage result = new HttpResponseMessage { Content = new StringContent(jsonString, Encoding.GetEncoding("UTF-8"), "application/json") };
return result;
}
// GET
public HttpResponseMessage Get(String WebURL, String HeaderPath, String FooterPath)
{
UrlToPng4Web.InitUrlTOPng4CS();
Web2PNGRequest req = new Web2PNGRequest();
req.WebURL = WebURL;
req.HeaderPath = HeaderPath;
req.FooterPath = FooterPath;
Web2PNGResponse rsp = UrlToPng4Web.UrlToPNG(req);
String jsonString = JsonConvert.SerializeObject(rsp);
HttpResponseMessage result = new HttpResponseMessage { Content = new StringContent(jsonString, Encoding.GetEncoding("UTF-8"), "application/json") };
return result;
}
// POST
public HttpResponseMessage Post(Web2PNGRequest req)
{
UrlToPng4Web.InitUrlTOPng4CS();
Web2PNGResponse rsp = UrlToPng4Web.UrlToPNG(req);
String jsonString = JsonConvert.SerializeObject(rsp);
HttpResponseMessage result = new HttpResponseMessage { Content = new StringContent(jsonString, Encoding.GetEncoding("UTF-8"), "application/json") };
return result;
}
}
}
首先是服务端:
1、增加服务类
package com.neohope.jessery.test;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
/**
* Created by Hansen
*/
@Path("neotest")
@Produces(MediaType.APPLICATION_JSON)
public class NeoTest {
@GET
@Path("/Add")
public String Add(@QueryParam("a") int a,@QueryParam("b") int b) {
return "{\"c\":" + (a+b) + "}";
}
@GET
@Path("/SayHiTo")
public String sayHiTo(@QueryParam("name") String name) {
return "{\"msg\":\"hi " + name + "\"}";
}
}
2、在web.xml里增加配置
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.neohope.jessery.test</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/Rest/*</url-pattern>
</servlet-mapping>
3、然后是客户端
package com.neohope.jessery.test;
import org.glassfish.jersey.client.ClientConfig;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;
/**
* Created by Hansen
*/
public class ClientTest {
public static void main(String[] args) {
ClientConfig clientConfig = new ClientConfig();
Client client = ClientBuilder.newClient(clientConfig);
WebTarget target = client.target("http://localhost:8080/Rest/neotest/" + "Add");
Response response = target.queryParam("a", 1).queryParam("b", 2).request().get();
System.out.println(response.getStatus());
System.out.println(response.readEntity(String.class));
response.close();
WebTarget target1 = client.target("http://localhost:8080/Rest/neotest/" + "SayHiTo");
Response response1 = target1.queryParam("name", "neohope").request().get();
System.out.println(response1.getStatus());
System.out.println(response1.readEntity(String.class));
response1.close();
}
}
一般有两种方式实现:
1、通过代码设置直接实现
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Text;
using WcfTest;
namespace WcfHosting
{
internal class Program
{
private static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof (SoapService)))
{
host.AddServiceEndpoint(typeof(ISoapService), new WSHttpBinding(), "http://127.0.0.1:1234/neohope");
if (host.Description.Behaviors.Find<ServiceMetadataBehavior>() == null)
{
ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
behavior.HttpGetEnabled = true;
behavior.HttpGetUrl = new Uri("http://127.0.0.1:9999/neohope/metadata");
host.Description.Behaviors.Add(behavior);
}
host.Opened += delegate
{
Console.WriteLine("service started, press enter to exit.");
};
host.Open();
Console.Read();
}
}
}
}
2、通过配置文件实现
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Text;
using WcfTest;
namespace WcfHosting
{
internal class Program
{
private static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof (SoapService)))
{
host.Opened += delegate
{
Console.WriteLine("service started, press enter to exit.");
};
host.Open();
Console.Read();
}
}
}
}
app.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="metadataBehavior">
<serviceMetadata httpGetEnabled="true" httpGetUrl="http://127.0.0.1:9999/neohope/metadata" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="metadataBehavior" name="WcfTest.SoapService">
<endpoint address="http://127.0.0.9999/neohope" binding="wsHttpBinding"
contract="WcfTest.ISoapService" />
</service>
</services>
</system.serviceModel>
</configuration>