WebService 用法
一、WS理论篇
MQ和WS技术相结合其实就可以看做是一个简单的ESB程序,这样可以通过调用服务来实现消息中间件的处理功能,可以开发包括消息推送、接收、处理的应用程序。WS是在Windows操作系统中才会有的,是集成到系统中的,一个WS在开启后会一直运行,直到停止该WS。在具体的项目中开发的WS是作为组件存在的,也就是说系统中的某部分需要实时运行,这时候可以考虑开发WS组件。
1.1 windows service VS web service
那么这里需要思考一个问题,windows Service和web Service它们两个都是服务,但是服务的对象是不同的。在web应用程序中web service是一个行业的信息服务标准,它为web应用程序之间架设了一个桥梁,使得应用程序之间可以互相的交流通信,也就是说web service是在web分布式应用中必然会用到的技术。
相较下来windows Service就比较狭窄了,它只能在windows system中运行,可以为windows的应用提供功能服务上的支持,在开发windows Service时常常会考虑两种情况,一是运行的组件考虑需要实时运行,另外是组件可以需要被多个程序调用,比如经常在开发中用到的sql server,它有很多子程序,这些程序之间会共用某个功能,所以此时就把它做成了一个服务。
1.2 ws开发
ws的组成是比较简单的,因为它本身固有的属性很少,大部分功能是通过调用其它的类库或者组件来组合功能,具体的ws的组成如下导图所示:
在开发ws时会有两个大的部分,分别是Service和Installer,Service是服务的内部功能逻辑,也就是服务的本体,服务要做的操作都是写到里面的;Installer是服务的安装部分,也就是配置了该服务在windows中显示的属性。
Service:继承自ServiceBase,其中包括服务所有的运行内容,开发界面类似于winForm中的自定义控件的开发,能够添加系统控件及第三方控件。
Installer:分为两种,其中的serviceProcessInstaller配置服务的被调用的用户类型,serviceInstaller配置服务本身属性,如服务名称、服务启动方法等。
二、WS Demo
上文对WS的基本内容做了详细的了解,通过理论来指导实践,这样在开发的时候思路才能够很清晰,关于WS的理论部分这里不再详细的讨论,接下来我们开发一个简单的WS Demo。
上篇文章详细讨论了MQ的开发方法,并开发了一个简单的MQ项目,这里就继续使用上文的MQ的项目来开发一个对MQ消息处理的WS组件,该组件主要是负责处理消息队列中的信息,获取消息,并把消息的主题内容保存到文本中。
具体程序的分布图如下所示:
2.1 服务代码
上面的程序分布图是结合上文的MQ来绘制的详细的架构图,其中的数据发送部分的程序在上文已经有介绍,这里不再详细讨论,下面的代码就是演示了分布图中的Service Handle data和Save data部分的功能,具体功能如下代码:
- using System;
- using System.IO;
- using System.ServiceProcess;
- using System.Threading;
- using System.Timers;
- using System.Messaging;
- namespace WindowsService1
- {
- public partial class Service1 : ServiceBase
- {
- //declare a MQ
- private MessageQueue queue;
- public Service1()
- {
- InitializeComponent();
- //create a path for queue
- string strpath = ".\\Private$\\EKTestQueue";
- //create a messagequeue and assign a path for this queue
- queue= new MessageQueue(strpath);
- //the queue formatter that can get queuebody based on the formatter
- queue.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });
- }
- /// <summary>
- /// service start event
- /// when we start this service then it will run this method
- /// </summary>
- /// <param name="args"></param>
- protected override void OnStart(string[] args)
- {
- //used to debug the code when start this service
- Thread.Sleep(30000);
- }
- /// <summary>
- /// service stop event
- /// </summary>
- protected override void OnStop()
- {
- }
- /// <summary>
- /// get message from queue and save the message to file
- /// </summary>
- private void GetAndWriteMessage()
- {
- //recevie a new one MQ
- var ms=queue.Receive();
- //save the data to file
- if (ms!=null)
- {
- this.AddTextLine(ms.Body.ToString());
- }
- }
- /// <summary>
- /// save the MQ message to file
- /// </summary>
- /// <param name="line">the message that want save</param>
- private void AddTextLine(string line)
- {
- try
- {
- //save the message to Message.txt file
- FileStream file=new FileStream("D:\\Message.txt",FileMode.OpenOrCreate,FileAccess.ReadWrite);
- StreamWriter writer=new StreamWriter(file);
- writer.BaseStream.Seek(0, SeekOrigin.End);
- writer.WriteLine(line+"\r\n");
- writer.Flush();
- writer.Close();
- file.Close();
- file.Dispose();
- }
- catch (Exception ex)
- {
- throw new Exception(ex.Message);
- }
- }
- private void timer1_Elapsed(object sender, ElapsedEventArgs e)
- {
- GetAndWriteMessage();
- }
- }
- }
using System;
using System.IO;
using System.ServiceProcess;
using System.Threading;
using System.Timers;
using System.Messaging; namespace WindowsService1
{
public partial class Service1 : ServiceBase
{
//declare a MQ
private MessageQueue queue;
public Service1()
{
InitializeComponent(); //create a path for queue
string strpath = ".\\Private$\\EKTestQueue";
//create a messagequeue and assign a path for this queue
queue= new MessageQueue(strpath);
//the queue formatter that can get queuebody based on the formatter
queue.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });
} /// <summary>
/// service start event
/// when we start this service then it will run this method
/// </summary>
/// <param name="args"></param>
protected override void OnStart(string[] args)
{
//used to debug the code when start this service
Thread.Sleep(30000);
} /// <summary>
/// service stop event
/// </summary>
protected override void OnStop()
{
}
/// <summary>
/// get message from queue and save the message to file
/// </summary>
private void GetAndWriteMessage()
{
//recevie a new one MQ
var ms=queue.Receive();
//save the data to file
if (ms!=null)
{
this.AddTextLine(ms.Body.ToString());
}
} /// <summary>
/// save the MQ message to file
/// </summary>
/// <param name="line">the message that want save</param>
private void AddTextLine(string line)
{
try
{
//save the message to Message.txt file
FileStream file=new FileStream("D:\\Message.txt",FileMode.OpenOrCreate,FileAccess.ReadWrite); StreamWriter writer=new StreamWriter(file);
writer.BaseStream.Seek(0, SeekOrigin.End);
writer.WriteLine(line+"\r\n");
writer.Flush();
writer.Close();
file.Close();
file.Dispose();
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
} private void timer1_Elapsed(object sender, ElapsedEventArgs e)
{
GetAndWriteMessage();
}
}
}
上面的代码主要是在服务中添加了信息处理的模块,这样就能够实现时时获取queue中的数据并对数据进行操作。
Note1:在服务的OnStart事件中添加了Thread.Sleep(3000)是为了调试服务启动代码而存在的,因为服务启动的时候是很快的也就是说我们在调试代码时经常会将项目附加到服务中,但是这时候服务是已经启动的了,是没有办法调试它的,所以我们添加了改行代码,这样就可以延迟服务的启动时间,给我们制造了充足的时间将代码附加到服务中来调试服务的启动代码。
Note2:Timer控件,该控件一定要是System.Timers.Timer控件,因为在添加时可能会误添加为在Thread命名空间下载Timer控件,这样就会导致服务在启动时出错,不能正常注册该控件。
2.2 服务调试
在开发完成服务后不能够直接运行使用,而是要将服务安装到系统的Services中才能够查看服务是否正常运行,因为服务不同于一般的应用程序,想要使用服务就必须将服务安装到系统当中。另外服务的调试也是很麻烦的一件事,因为服务不同于应用程序,想要调试它就不能采用普通的调试方法了,这里介绍一种附加进程的调试方法,还有其它如写日志等的调试方法,可以查看网上的文章来详细了解。
2.2.1 安装服务
首先要打开控制台并进入到C:/Windows/Microsoft.Net/Framework/v4.0.30319中,运行InstallUtil.exe工具,并添加相应的开发的服务程序,然后回车运行就可以安装,如下所示:
C:/Windows/Microsoft.Net/Framework/v4.0.30319>InstallUtil.exe C:\Code\WindowsService1\WindowsService1\bin\Debug\WindowsService1.exe
安装完成后查看Services工具中的服务如下图所示:
安装后服务显示的名称是根据ServiceInstaller的属性来控制的,在开发时指定了ServiceName属性名称为Jack's Service所以安装后显示的服务名称如上图所示。
2.2.2 将WS附加到进程
首先打开Tools下面的Attach to Process窗体,然后在程序中找到该服务,具体如下面两张图所示:
找到后双击该程序即可将添加源码到服务,这时候就能够对服务的代码进行调试了。
Note3:在附加进程时,所附加的进程名称是和服务的程序名称相一致的,并不是和Services工具中的名称一致。因为该服务程序的名称为WindowsServices1所以我们要把代码附加到该服务中,如上图所示。
2.2.3 删除服务
在不使用服务后也可以删除服务,删除方法类似于服务的安装,具体方法如下所示:
C:/Windows/Microsoft.Net/Framework/v4.0.30319>InstallUtil.exe/u C:\Code\WindowsService1\WindowsService1\bin\Debug\WindowsService1.exe
结语
文章主要介绍了WS的基本构成,并通过一个具体的示例来演示开发WS时需要注意的地方,最后介绍了一种WS的调试方法,很简单,但是新手会有很多问题,具体的问题具体分析,可以留言讨论。
WS在分布式开发中拥有重要作用,它能够协调各个程序之前的交互功能,可以作为程序的通信桥梁,但是WS本身有很多局限性,它只能运行在Windows系统中,另外WS的代码调试一直惨遭诟病,需要开发人员一次次的安装、附加进程、删除的操作,很耗费时间,所以在做分布式开发时一定要慎重考虑使用WS。
版权声明:本文为博主原创文章,未经博主允许不得转载。
WebService 用法的更多相关文章
- JEECG(二) JEECG框架下调用webservice java springmvc maven 调用 webservice
JEECG系列教程二 如何在JEECG框架下使用webservice 本文所使用的webservice是c#开发的 其实无论是什么语言开发的webservice用法都一样 java springmvc ...
- pb相关小技巧或用法
1.动态post window lwlw = w_main lw.dynamic post event ue_all(ls_no,ls_table) 2.打开隐藏窗口 IF NOT IsValid(w ...
- Android webservice的用法详细讲解
Android webservice的用法详细讲解 看到有很多朋友对WebService还不是很了解,在此就详细的讲讲WebService,争取说得明白吧.此文章采用的项目是我毕业设计的webserv ...
- ajax——client访问webservice基本用法
学前aps.net当我学会了使用服务器端的访问webservice方法,然后实现一个样本:web server模拟网上购物,今天学习asp.net ajax的时候学习到了client直接訪问webse ...
- php无wsdl webservice服务用法
服务端: <?php class test { function add($a,$b) { return $a+$b; } } function getUserInfo($name) { ret ...
- Jaxb的优点与用法(bean转xml的插件,简化webservice接口的开发工作量)
一.jaxb是什么 JAXB是Java Architecture for XML Binding的缩写.可以将一个Java对象转变成为XML格式,反之亦然. 我们把对象与关系数据库之间的映射称 ...
- WebService基本使用
不使用任何框架,纯粹使用JDK开发一个服务端与客户端 服务端 package org.zln.ws.server;import org.slf4j.Logger;import org.slf4j.Lo ...
- 性能测试总结工作总结-基于WebService协议脚本 内置函数手动编写
LoadRunner基于WebService协议脚本 WebService协议脚本有三种生成方式,一种是直接通过LoadRunner导入URL自动解析生成:一种是使用LoadRunner内置函数手动编 ...
- 如何使用C#创建WebService
使用C#创建WebService,服务端的webservice是必须,中间的soap,Xml我们不用去关心.下面是使用C#创建WebService的简单介绍. AD:51CTO技术沙龙 | 赋予APP ...
随机推荐
- 数迹学——Asp.Net MVC4入门指南(5):从控制器访问数据模型
MovieController中的方法Index()代码,初认识,应该有很多理解错误的地方,暂时这么记忆吧,待随后修改 Index()代码: @model IEnumerable<MVCMovi ...
- XMLHttpRequest
XMLHttpRequest对象的方法 abort() 取消当前所发出的请求 getAllResponseHeaders() 取得所有的HTTP头信息 getResponseHeader() 取得一个 ...
- Nginx-Lua模块的执行顺序
一.nginx执行步骤 nginx在处理每一个用户请求时,都是按照若干个不同的阶段依次处理的,与配置文件上的顺序没有关系,详细内容可以阅读<深入理解nginx:模块开发与架构解析>这本书, ...
- jq 获取元素的宽度时,如何取得小数部分
<!DOCTYPE html> <html> <head> <title></title> <meta name="arti ...
- NHibernate Demo 和 效率测试
本文关于NHibernate的Demo和效率测试,希望对大家有用. 1.先去官网下载Nhibernate 2.放入到项目中并建立Helper类 private static ISession _Ses ...
- jcmd、jmc介绍
一.jcmd命令使用 概述 在JDK 1.7之后,新增了一个命令行工具jcmd.它是一个多功能工具,可以用来导出堆,查看Java进程,导出线程信息,执行GC等. 使用示例 下面这个命令能够列出当前运行 ...
- [HTML] IE=edge,chrome=1的META标签详解
文件兼容性用于定义让IE如何编译你的网页.此文件解释文件兼容性,如何指定你网站的文件兼容性模式以及如何判断一个网页该使用的文件模式. meta信息中常有这么一句: <meta content=& ...
- SQL: ROW_NUMBER
- Oracle定时查询结果输出到指定的log文件
最近有个监控项目需要采集数据库信息,原来方案是写个sql脚本,每个脚本放一个查询语句然后通过操作系统层su到oracle用户通过sqlpus执行这个.sql,然后加到crontab定时执行.但是这个问 ...
- 【HOW】如何手工编辑InfoPath文件
因为直接打开InfoPath的配置文件进行编辑会有些无从下手,所以下面以修改“节”的Margin为例来说明手工编辑InfoPath文件的过程. 1. 新建一个“节”,并在此节中创建一个数字类型字段“n ...