DCOM简单示例(01)

本篇文章介绍了如何写一个简单的DCOM服务端(EXE模式)。

1、VC新建工程,ATL->ATL Project(名称为ATLExe)->类型选择Executable(EXE)->Finish

2、工程视图,ATLExe工程,右键->Add->Class->ATL->ATL Simple Object->类名为JustATestExe,ProgID为ATLExe.JustATestExe

3、切换到类视图,ATLExe项目下的IJustATestExe接口上右键Add Method
名称:Add
参数1:[in]LONG a
参数2:[in]LONG b
参数3:[out,retval]LONG* c

4、类视图,ATLExe项目下的IJustATestExe接口上右键Add Method
名称:SayHiTo
参数1:[in]BSTR someOne
参数2:[out,retval]BSTR* retValue

5、打开JustATestExe.cpp完成两个函数

STDMETHODIMP CJustATestExe::Add(LONG a, LONG b, LONG* c)
{
	// TODO: Add your implementation code here
	*c = a+b;

	return S_OK;
}


STDMETHODIMP CJustATestExe::SayHiTo(BSTR someOne, BSTR* retValue)
{
	// TODO: Add your implementation code here
	CComBSTR sResult("Hi ");
	CComBSTR sName(someOne);
	CComBSTR sMark("!");
	sResult.AppendBSTR(sName);
	sResult.AppendBSTR(sMark);
	*retValue = sResult.Copy();

	return S_OK;
}

6、编译

7、注册

ATLExe.exe /regserver

8、反注册

ATLExe.exe /unregserver

ATL三种项目的使用方式

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服务授权配置

远程调用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操作

ATL NT Service 调用超时

最近发现了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'
		}
	}
}

重新编译后,就可以调用成功了。

好坑啊!

微软MVC实现REST风格编程

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;
        }
    }
}

Jersey实现REST风格编程

首先是服务端:
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();
    }
}

WCF自托管服务

一般有两种方式实现:

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>

WCF修改SOAP命名空间

有三个地方可以修改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>

WCF实现REST风格编程

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

JBoss EAP MessageBean的调用(Queue)

通讯流程图,其中EJB扮演了Client2的角色
jms-point-to-point-model.png

首先是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();
    }
}