ATL向导允许我们建立三种项目:
1、DLL
2、EXE
3、NT服务
三种项目的使用方式如下:
1、DLL
A、注册
regsvr32 xxx.dll
B、反注册
regsvr32 /u xxx.dll
2、EXE
A、注册
xxx.exe /regserver
B、反注册
xxx.exe /unregserver
3、NT服务
A、注册
xxx.exe /service
B、反注册
xxx.exe /unregserver
Learn and share.
ATL向导允许我们建立三种项目:
1、DLL
2、EXE
3、NT服务
三种项目的使用方式如下:
1、DLL
A、注册
regsvr32 xxx.dll
B、反注册
regsvr32 /u xxx.dll
2、EXE
A、注册
xxx.exe /regserver
B、反注册
xxx.exe /unregserver
3、NT服务
A、注册
xxx.exe /service
B、反注册
xxx.exe /unregserver
远程调用DCOM时经常会遇到下面的错误:
Error: 70 Description: Permission denied
这时就要进行授权。
首先是服务端配置:
1、首先在DCOM服务端新建一个用户,比如DCOMTEST
2、在DCOM服务端运行
#32位系统32位COM,64位系统64位COM dcomcnfg #64位系统32位COM comexp.msc -32
3、在“服务组件-》计算机-》我的电脑”右键,属性
默认属性-》确认DCOM服务开启
4、在“服务组件-》计算机-》我的电脑-》DCOM配置”,对应的DCOM组件上,右键,属性
常规-》身份验证级别-》无
安全-》启动与激活权限,添加新增用户DCOMTEST,并授权
安全-》访问权限,添加新增用户DCOMTEST,并授权
然后是客户端配置
1、在客户端,添加服务端的DCOMTEST用户凭证
搞定!
PS:如果还不行的话,再设置下面的内容
1、在“服务组件-》计算机-》我的电脑”右键,属性
默认属性-》将默认身份验证基本修改为无
默认属性-》将默认模拟级别改为匿名
COM安全-》访问权限,添加Everyone及匿名用户
COM安全-》启动与激活权限,添加Everyone及匿名用户
2、然后要修改一下本地安全策略,让匿名用户与Everyone权限相同
3、然后修改本地安全策略,让DCOM可以Everyone操作
最近发现了VS(VS2008,VS2010,VS2012,VS2013)的一个大Bug,就是在新建ATL项目时,如果直接选择Service,则服务无将法正确调用。其表现为:
在客户端调用CoCreateInstance或CreateObject会返回:
Error: 429 Description: ActiveX 部件不能创建对象
在服务端会返回(CLSID会根据实际情况发生变化):
The server {7A387102-53AE-4A3A-8F28-5EE76C2BC1E4} did not register with DCOM within the required timeout.
服务器 {7A387102-53AE-4A3A-8F28-5EE76C2BC1E4} 没有在限定的时间内用 DCOM 注册。
经过多方排查,最后发现,是在rgs文件中少了一行
val AppID = s '%APPID%'
调整后的rgs文件如下:
HKCR
{
ATLService.JustATestSvc.1 = s 'JustATestSvc Class'
{
CLSID = s '{7A387102-53AE-4A3A-8F28-5EE76C2BC1E4}'
}
ATLService.JustATestSvc = s 'JustATestSvc Class'
{
CurVer = s 'ATLService.JustATestSvc.1'
}
NoRemove CLSID
{
ForceRemove {7A387102-53AE-4A3A-8F28-5EE76C2BC1E4} = s 'JustATestSvc Class'
{
ProgID = s 'ATLService.JustATestSvc.1'
VersionIndependentProgID = s 'ATLService.JustATestSvc'
ForceRemove Programmable
LocalServer32 = s '%MODULE%'
{
val ServerExecutable = s '%MODULE_RAW%'
}
val AppID = s '%APPID%'
TypeLib = s '{9D5B6B0C-85D6-4DB6-B88A-915180B89038}'
Version = s '1.0'
}
}
}
重新编译后,就可以调用成功了。
好坑啊!
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>
有三个地方可以修改SOAP的命名空间:
1、ServiceContract
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.Web.Configuration;
namespace WcfTest
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
[ServiceContract(Name="SoapService",Namespace="http://wcftest.neohope.org")]
public interface ISoapService
{
[OperationContract]
[WebInvoke(Method = "GET", UriTemplate = "User/Get/{uid}", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
NUser GetUser(String uid);
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "/User", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
string UpdateUser(NUser newuser);
[OperationContract]
[WebInvoke(Method = "PUT", UriTemplate = "/User", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
string AddUser(NUser newuser);
[OperationContract]
[WebInvoke(Method = "DELETE", UriTemplate = "/User", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
string DeleteUser(String uid);
}
[ServiceBehavior(Name = "SoapService", Namespace = "http://wcftest.neohope.org")]
[DataContract]
public class NUser
{
string uid = "";
string uname = "";
string usex = "";
[DataMember]
public String Uid
{
get { return uid; }
set { uid = value; }
}
[DataMember]
public string UName
{
get { return uname; }
set { uname = value; }
}
[DataMember]
public string USex
{
get { return usex; }
set { usex = value; }
}
}
}
2、服务实现
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace WcfTest
{
[ServiceBehavior(Name = "SoapService", Namespace = "http://wcftest.neohope.org")]
public class SoapService : ISoapService
{
static List<NUser> users = new List<NUser>();
static SoapService()
{
NUser aNUser = new NUser();
aNUser.Uid = "001";
aNUser.UName = "张三";
aNUser.USex = "男";
users.Add(aNUser);
}
public NUser GetUser(string uid)
{
foreach (NUser nuser in users)
{
if (nuser.Uid == uid)
{
return nuser;
}
}
return null;
}
public string UpdateUser(NUser newuser)
{
if (newuser == null)
{
return "nuewuser is null";
}
foreach (NUser nuser in users)
{
if (nuser.Uid == newuser.Uid)
{
nuser.UName = newuser.UName;
newuser.USex = nuser.USex;
return "User updated";
}
}
return "User not found";
}
public string AddUser(NUser newuser)
{
if (newuser == null)
{
return "nuewuser is null";
}
foreach (NUser nuser in users)
{
if (nuser.Uid == newuser.Uid)
{
nuser.UName = newuser.UName;
newuser.USex = nuser.USex;
return "User updated";
}
}
users.Add(newuser);
return "User added";
}
public string DeleteUser(String uid)
{
bool bFound = false;
for(int i=users.Count-1;i>=0;i--)
{
if (users[i].Uid == uid)
{
bFound = true;
users.RemoveAt(i);
}
}
if (!bFound)
{
return "User Not Found";
}
else
{
return "User Deleted";
}
}
}
}
3、Web.config
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="WcfTest.SoapService">
<endpoint binding="webHttpBinding" contract="WcfTest.ISoapService" bindingNamespace="http://wcftest.neohope.org"/>
</service>
</services>
<behaviors>
<endpointBehaviors>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="false" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
1、首先需要一个ServiceContract
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace WcfTest
{
[ServiceContract]
public interface IRestService
{
[OperationContract]
[WebInvoke(Method = "GET", UriTemplate = "User/Get/{uid}", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
NUser GetUser(String uid);
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "/User", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
string UpdateUser(NUser newuser);
[OperationContract]
[WebInvoke(Method = "PUT", UriTemplate = "/User", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
string AddUser(NUser newuser);
[OperationContract]
[WebInvoke(Method = "DELETE", UriTemplate = "/User", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
string DeleteUser(String uid);
}
[DataContract]
public class NUser
{
string uid = "";
string uname = "";
string usex = "";
[DataMember]
public String Uid
{
get { return uid; }
set { uid = value; }
}
[DataMember]
public string UName
{
get { return uname; }
set { uname = value; }
}
[DataMember]
public string USex
{
get { return usex; }
set { usex = value; }
}
}
}
2、然后需要实现服务
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using System.Text;
namespace WcfTest
{
public class RestService : IRestService
{
static List<NUser> users = new List<NUser>();
static RestService()
{
NUser aNUser = new NUser();
aNUser.Uid = "001";
aNUser.UName = "张三";
aNUser.USex = "男";
users.Add(aNUser);
}
public NUser GetUser(string uid)
{
foreach (NUser nuser in users)
{
if (nuser.Uid == uid)
{
return nuser;
}
}
return null;
}
public string UpdateUser(NUser newuser)
{
if (newuser == null)
{
return "nuewuser is null";
}
foreach (NUser nuser in users)
{
if (nuser.Uid == newuser.Uid)
{
nuser.UName = newuser.UName;
newuser.USex = nuser.USex;
return "User updated";
}
}
return "User not found";
}
public string AddUser(NUser newuser)
{
if (newuser == null)
{
return "nuewuser is null";
}
foreach (NUser nuser in users)
{
if (nuser.Uid == newuser.Uid)
{
nuser.UName = newuser.UName;
newuser.USex = nuser.USex;
return "User updated";
}
}
users.Add(newuser);
return "User added";
}
public string DeleteUser(String uid)
{
bool bFound = false;
for(int i=users.Count-1;i>=0;i--)
{
if (users[i].Uid == uid)
{
bFound = true;
users.RemoveAt(i);
}
}
if (!bFound)
{
return "User Not Found";
}
else
{
return "User Deleted";
}
}
}
}
3、修改服务的Markup
<%@ ServiceHost Language="C#" Debug="true" Service="WcfTest.RestService" CodeBehind="RestService.svc.cs"
Factory="System.ServiceModel.Activation.WebServiceHostFactory"%>
4、修改服务配置
添加serviceBehaviors、endpointBehaviors、service、endpoint
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service behaviorConfiguration="RestSvcBehavior" name="WcfTest.RestService">
<endpoint binding="webHttpBinding" contract="WcfTest.IRestService" address="" behaviorConfiguration="RestEPBehavior"/>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="RestEPBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="RestSvcBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="false" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
5、访问服务
http://ip:port/RestService.svc/User/Get/001
通讯流程图,其中EJB扮演了Client2的角色

首先是Server端的开发及设置:
1、增加一个用户:
bin\add-user.bat
用户名密码随便,但要属于guest组
2、启动Server
standalone.bat -server-config=standalone-full.xml
3、新建Queue
jboss-cli.bat --connect jms-queue add --queue-address=neoQueue --entries=queue/neoQueue,java:jboss/exported/jms/queue/neoQueue
4、新建java项目
4.1、写一个QueueBean
MessageQueueBean.java
package com.neohope.ejb.test;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.TextMessage;
/**
* Created by Hansen
*/
@MessageDriven(activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/neoQueue"),
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge")
})
public class MessageQueueBean implements javax.jms.MessageListener {
public MessageQueueBean() {
}
@Override
public void onMessage(Message message) {
try {
System.out.println("MessageQueueBean.onMessage invoked");
if(message instanceof TextMessage)
{
TextMessage textMessage = (TextMessage)message;
System.out.println("Message: " + textMessage.getText());
}
else
{
System.out.println("Message is not a TextMessage");
}
}
catch (JMSException e) {
e.printStackTrace();
}
}
}
4.2、打jar包,或者自己压缩为TestEJBServer.jar
5、新建一个ear项目
5.1增加application.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_6.xsd"
version="6">
<description>EAR Test</description>
<display-name>EAR Test</display-name>
<module>
<ejb>TestEJBServer.jar</ejb>
</module>
<library-directory>lib</library-directory>
</application>
5.2打ear包,或自己压缩为TestEar.ear
5.3TestEar的结构为:
│ TestEJBServer.jar
│
├─lib
└─META-INF
application.xml
6.通过EAP进行部署
到这里服务端已经完成了。
然后是客户端的设置:
1、通过Queue方式访问
package com.neohope.ejb.test;
import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.util.Hashtable;
/**
* Created by Hansen
*/
public class TestQueueBean {
public static void main(String[] args) throws NamingException, JMSException {
final Hashtable jndiProperties = new Hashtable();
jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
jndiProperties.put(Context.PROVIDER_URL, "remote://localhost:4447");
final InitialContext ctx = new InitialContext(jndiProperties);
QueueConnectionFactory factory = (QueueConnectionFactory) ctx.lookup("jms/RemoteConnectionFactory");
QueueConnection connection = factory.createQueueConnection("user001", "user001#");
QueueSession session = connection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
Queue queue = (Queue) ctx.lookup("jms/queue/neoQueue");
TextMessage msg = session.createTextMessage("Queue Test Messagee");
QueueSender sender = session.createSender(queue);
sender.send(msg);
session.close();
connection.close();
}
}
2、通过MessageProducer方式访问
package com.neohope.ejb.test;
import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.util.Hashtable;
/**
* Created by Hansen
*/
public class TestQueueBean {
public static void main(String[] args) throws NamingException, JMSException {
final Hashtable jndiProperties = new Hashtable();
jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
jndiProperties.put(Context.PROVIDER_URL, "remote://localhost:4447");
final InitialContext ctx = new InitialContext(jndiProperties);
ConnectionFactory connectionFactory = (ConnectionFactory) ctx.lookup("jms/RemoteConnectionFactory");
Destination destination = (Destination) ctx.lookup("jms/queue/neoQueue");
Connection connection = connectionFactory.createConnection("user001", "user001#");
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = session.createProducer(destination);
connection.start();
TextMessage msg = session.createTextMessage("Queue Test Messagee");
producer.send(msg);
session.close();
connection.close();
}
}
通讯流程图,其中EJB扮演了client2的角色

首先是Server端的开发及设置:
1、增加一个用户:
bin\add-user.bat
用户名密码随便,但要属于guest组
2、启动Server
standalone.bat -server-config=standalone-full.xml
3、新建Topic
jboss-cli.bat --connect jms-topic add --topic-address=neoTopic --entries=topic/neoTopic,java:jboss/exported/jms/topic/neoTopic
4、新建java项目
4.1、写一个TopicBean
MessageTopicBean .java
package com.neohope.ejb.test;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.TextMessage;
/**
* Created by Hansen
*/
@MessageDriven(mappedName = "MessageTopicBean",activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "topic/neoTopic"),
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge")
})
public class MessageTopicBean implements javax.jms.MessageListener {
public MessageTopicBean() {
}
@Override
public void onMessage(Message message) {
try {
System.out.println("MessageTopicBean.onMessage invoked");
if(message instanceof TextMessage)
{
TextMessage textMessage = (TextMessage)message;
System.out.println("Message: " + textMessage.getText());
}
else
{
System.out.println("Message is not a TextMessage");
}
}
catch (JMSException e) {
e.printStackTrace();
}
}
}
4.2、打jar包,或者自己压缩为TestEJBServer.jar
5、新建一个ear项目
5.1增加application.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_6.xsd"
version="6">
<description>EAR Test</description>
<display-name>EAR Test</display-name>
<module>
<ejb>TestEJBServer.jar</ejb>
</module>
<library-directory>lib</library-directory>
</application>
5.2打ear包,或自己压缩为TestEar.ear
5.3TestEar的结构为:
│ TestEJBServer.jar
│
├─lib
└─META-INF
application.xml
6.通过EAP进行部署
到这里服务端已经完成了。
然后是客户端的设置:
1、通过Topic方式访问
package com.neohope.ejb.test;
import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.util.Hashtable;
/**
* Created by Hansen
*/
public class TestTopicBean {
public static void main(String[] args) throws NamingException, JMSException {
final Hashtable jndiProperties = new Hashtable();
jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
jndiProperties.put(Context.PROVIDER_URL, "remote://localhost:4447");
final InitialContext ctx = new InitialContext(jndiProperties);
TopicConnectionFactory factory = (TopicConnectionFactory) ctx.lookup("jms/RemoteConnectionFactory");
TopicConnection connection = factory.createTopicConnection("user001", "user001#");
TopicSession session = connection.createTopicSession(false, TopicSession.AUTO_ACKNOWLEDGE);
Topic topic = (Topic) ctx.lookup("jms/topic/neoTopic");
TextMessage msg = session.createTextMessage("Topic Test Message");
TopicPublisher publisher = session.createPublisher(topic);
publisher.publish(msg);
session.close();
connection.close();
}
}
2、通过MessageProducer方式访问
package com.neohope.ejb.test;
import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.util.Hashtable;
/**
* Created by Hansen
*/
public class TestTopicBean {
public static void main(String[] args) throws NamingException, JMSException {
final Hashtable jndiProperties = new Hashtable();
jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
jndiProperties.put(Context.PROVIDER_URL, "remote://localhost:4447");
final InitialContext ctx = new InitialContext(jndiProperties);
ConnectionFactory connectionFactory = (ConnectionFactory) ctx.lookup("jms/RemoteConnectionFactory");
Destination destination = (Destination) ctx.lookup("jms/topic/neoTopic");
Connection connection = connectionFactory.createConnection("user001", "user001#");
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = session.createProducer(destination);
connection.start();
TextMessage msg = session.createTextMessage("Topic Test Messagee");
producer.send(msg);
session.close();
connection.close();
}
}