Calling my azure bot service using websocket fails - rest

I have an Azure bot service which runs perfectly when tested on webchat.
Now I tried to open a websocket and test the bot.
I first send a POST request (with all required headers) to https://directline.botframework.com/v3/directline/conversations
I get a response with
{
"conversationId": "7FY18sO6FCT9OVi0pW7WBY",
"token": "my_token_here",
"expires_in": 1800,
"streamUrl":
"wss://directline.botframework.com/v3/directline/conversations/7FY18sO6FCT9OVi0pW7WBY/stream?watermark=-&t=token_value_here",
"referenceGrammarId": "c1c290dd-f896-5857-b328-cdc10298e440"
}
Now I try to use the streamUrl to send/receive data using web socket.
I got an error: Undefined
I tried to test the streamUrl on different online websocket testing tool. I still got the undefined error.
How can I test whether there is a problem in the streamUrl?
How can I test the web socket?

Firstly, as Eric Dahlvang mentioned, it enables us to receive activities via WebSocket stream, but not send activities.
Besides, I do a test with the following steps and sample, the activities can be received as expected via WebSocket stream, you can refer to it.
Step1: make a request to start a conversation
Step2: start client app (a console application) to wait for receiving acitivities
class Program
{
private static string botId = "fehanbasicbot";
static void Main(string[] args)
{
var url = Console.ReadLine();
StartReceivingActivities(url).Wait();
Console.ReadLine();
}
private static async Task StartReceivingActivities(string url)
{
var webSocketClient = new WebSocket(url);
webSocketClient.OnMessage += WebSocketClient_OnMessage;
webSocketClient.Connect();
}
private static void WebSocketClient_OnMessage(object sender, MessageEventArgs e)
{
// Occasionally, the Direct Line service sends an empty message as a liveness ping. Ignore these messages.
if (string.IsNullOrWhiteSpace(e.Data))
{
return;
}
var activitySet = JsonConvert.DeserializeObject<ActivitySet>(e.Data);
var activities = from x in activitySet.Activities
where x.From.Id == botId
select x;
foreach (Activity activity in activities)
{
Console.WriteLine(activity.Text);
}
}
}
packages.config
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Bot.Connector.DirectLine" version="3.0.2" targetFramework="net461" />
<package id="Microsoft.Rest.ClientRuntime" version="2.3.2" targetFramework="net461" />
<package id="Newtonsoft.Json" version="6.0.8" targetFramework="net461" />
<package id="WebSocketSharp" version="1.0.3-rc11" targetFramework="net461" />
</packages>
Step3: make a request to send an activity to the bot
Step4: check the console app output, I can find the activities are received

Related

Mono WCF Rest Service With Multiple Contracts "no endpoints are defined in the configuration file"

I want to host a WCF Rest Service with multiple contracts via mono each implemented in a separate partial class. I read many posts on similar issues, yet there was no solution for mono. I incorporated or at least tested all suggestions I could find and by now my code looks a lot like other solutions, yet does not work.
The application runs successfully on my local machine but throws an error once I deploy it via mono.
Service 'MyWebServiceEndpoint' implements multiple ServiceContract types, and no endpoints are defined in the configuration file.
Here is one of the endpoints with the contract. All the others are very much like this one. They all are a partial class MyWebServiceEndpoint implementing another contract.
namespace MyServer.MyEndPoints {
public partial class MyWebServiceEndpoint : INotificationEndpoint {
public string GetNotifications(int limit) {
// Do stuff
}
}
[ServiceContract]
public interface INotificationEndpoint {
[OperationContract]
[WebGet]
string GetNotifications(int limit);
}
}
My App.config looks like this. I removed the IP and port, as they are the server address.
<system.serviceModel>
<services>
<service name="MyServer.MyEndPoints.MyWebServiceEndpoint" behaviorConfiguration="WebService.EndPoint">
<host>
<baseAddresses>
<add baseAddress="http://ip:port>"/>
</baseAddresses>
</host>
<endpoint address="/message"
binding="webHttpBinding"
contract="MyServer.MyEndPoints.IMessageEndpoint"
behaviorConfiguration="WebBehavior"/>
<endpoint address="/music"
binding="webHttpBinding"
contract="MyServer.MyEndPoints.IMusicEndpoint"
behaviorConfiguration="WebBehavior"/>
<endpoint address="/notification"
binding="webHttpBinding"
contract="MyServer.MyEndPoints.INotificationEndpoint"
behaviorConfiguration="WebBehavior"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WebService.EndPoint">
<serviceMetadata httpGetEnabled="True" />
<serviceDebug includeExceptionDetailInFaults="True"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="WebBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
I open the service in C# like this.
WebServiceHost = new WebServiceHost(typeof(MyWebServiceEndpoint));
WebServiceHost.Open();
The Error message I receive on mono is:
Unhandled Exception:
System.InvalidOperationException: Service 'MyWebServiceEndpoint' implements multiple ServiceContract
types, and no endpoints are defined in the configuration file. WebServiceHost can set up default
endpoints, but only if the service implements only a single ServiceContract. Either change the
service to only implement a single ServiceContract, or else define endpoints for the service
explicitly in the configuration file. When more than one contract is implemented, must add base
address endpoint manually
I hope you have some hints or someone knows how to solve the issue. Thank you already for reading up to here.
I am not familiar with Mono, Does the Mono support Webconfig file? I advise you to add the service endpoint programmatically.
class Program
{
/// <param name="args"></param>
static void Main(string[] args)
{
WebHttpBinding binding = new WebHttpBinding();
Uri uri = new Uri("http://localhost:21011");
using (WebServiceHost sh = new WebServiceHost(typeof(TestService),uri))
{
sh.AddServiceEndpoint(typeof(ITestService), binding, "service1");
sh.AddServiceEndpoint(typeof(IService), binding, "service2");
ServiceMetadataBehavior smb;
smb = sh.Description.Behaviors.Find<ServiceMetadataBehavior>();
if (smb == null)
{
smb = new ServiceMetadataBehavior()
{
HttpGetEnabled = true
};
sh.Description.Behaviors.Add(smb);
}
sh.Opened += delegate
{
Console.WriteLine("service is ready");
};
sh.Closed += delegate
{
Console.WriteLine("service is closed");
};
sh.Open();
Console.ReadLine();
sh.Close();
}
}
}
[ServiceContract]
public interface ITestService
{
[OperationContract]
[WebGet]
string GetData(int id);
}
[ServiceContract]
public interface IService
{
[OperationContract]
[WebGet]
string Test();
}
public class TestService : ITestService,IService
{
public string GetData(int id)
{
return $"{id},";
}
public string Test()
{
return "Hello " + DateTime.Now.ToString();
}
}
Result.
According to the official documentation, we had better not use Partial class.
https://learn.microsoft.com/en-us/dotnet/framework/wcf/samples/multiple-contracts
Besides, we could consider launching multiple service host for every service implemented class.
Feel free to let me know if the problem still exists.

Customizing Spring Integration Web Service SOAP Envelope/Header

I am trying to send a SOAP request using Spring Integration like
<int:chain input-channel="wsOutChannel" output-channel="stdoutChannel">
<int-ws:header-enricher>
<int-ws:soap-action value="..."/>
</int-ws:header-enricher>
<int-ws:outbound-gateway
uri="..."/>
</int:chain>
but you can only add the SOAP body, and Spring Integration adds the envelope, header, and body tags like
<SOAP-ENV:Envelope>
<SOAP-ENV:Header>
<SOAP-ENV:Body>
...
</SOAP-ENV:Body>
<SOAP-ENV:Header>
</SOAP-ENV:Envelope>
I need to customize the envelope and header tags with specific attributes, for example:
<soapenv:Envelope attribute1="value1" attribute2="value2">
and child elements, for example:
<soapenv:Header>
<child>...<child>
<soapenv:Header>
Is this possible with Spring Integration Web Services, or should I not use int-ws:outbound-gateway and take a different approach?
You can add a ClientInterceptor (via the interceptor attribute) which allows you to modify the request before it's sent out.
EDIT
#Artem's suggestion is simpler but the interceptor gives you access to the response too; but either way, the code is similar.
For the interceptor:
public class MyInterceptor extends ClientInterceptorAdapter {
#Override
public boolean handleRequest(MessageContext messageContext) throws WebServiceClientException {
SoapMessage request = (SoapMessage) messageContext.getRequest();
SoapEnvelope envelope = request.getEnvelope();
envelope.addAttribute(new QName("foo"), "bar");
SoapHeader header = envelope.getHeader();
header.addHeaderElement(new QName("http://fiz/buz", "baz"));
return super.handleRequest(messageContext);
}
}
For the callback version:
#Override
public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException {
SoapEnvelope envelope = ((SoapMessage) message).getEnvelope();
envelope.addAttribute(new QName("foo"), "bar");
SoapHeader header = envelope.getHeader();
header.addHeaderElement(new QName("http://fiz/buz", "baz"));
}
I thing you can inject WebServiceMessageCallback:
<xsd:attribute name="request-callback" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Reference to a Spring Web Services WebServiceMessageCallback. This enables changing
the Web Service request message after the payload has been written to it but prior
to invocation of the actual Web Service.
</xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.ws.client.core.WebServiceMessageCallback"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
and cast the message to the SoapMessage and use its getEnvelope() to customize a desired way.

How to implement SuperSocket

I am trying to implement Supersockets - https://supersocket.codeplex.com/ for a project i am working on. I have the a server that uses configuration to run.
In my project
I have referenced:
SuperSocket.Common,
SuperSocket.SocketBase,
SuperSocket.SocketEngine
I added the following config section:
<configSections>
<section name="superSocket" type="SuperSocket.SocketEngine.Configuration.SocketServiceConfig, SuperSocket.SocketEngine" />
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<appSettings>
<add key="ServiceName" value="SomeService" />
</appSettings>
<superSocket logFactory="ConsoleLogFactory"
disablePerformanceDataCollector="true"
maxWorkingThreads="500"
maxCompletionPortThreads="500"
minWorkingThreads="5"
minCompletionPortThreads="5">
<servers>
<server name="SomeService"
serverType="SomeService.Server.SomeService, SomeService"
ip="192.168.1.107"
port="4096"
disableSessionSnapshot="true"
clearIdleSession="false"
maxConnectionNumber="10"
sendWelcome="false">
</server>
</servers>
<logFactories>
<add name="ConsoleLogFactory"
type="SuperSocket.SocketBase.Logging.ConsoleLogFactory, SuperSocket.SocketBase" />
</logFactories>
</superSocket>
I also created the server and session class as follows:
namespace SomeService.Server
{
class SomeService: AppServer<SomeServiceSession>
{
protected override bool Setup(IRootConfig rootConfig, IServerConfig config)
{
return base.Setup(rootConfig, config);
}
protected override void OnStartup()
{
base.OnStarted();
}
protected override void OnStopped()
{
base.OnStopped();
}
}
}
namespace SomeService.Server
{
class SomeServiceSession : AppSession<SomeServiceSession>
{
protected override void OnSessionStarted()
{
// this.Send("Welcome to SuperSocket Telnet Server");
}
protected override void HandleUnknownRequest(StringRequestInfo requestInfo)
{
this.Send("Unknow request");
}
protected override void HandleException(Exception e)
{
this.Send("Application error: {0}", e.Message);
}
protected override void OnSessionClosed(CloseReason reason)
{
//add you logics which will be executed after the session is closed
base.OnSessionClosed(reason);
}
}
}
At this point the Server runs and it listens on a port as intended. Here is a wireshark representation of what i would want to do With SuperSocket http://imgur.com/rxKJbOD.
If you see on the request reply one chuck of the data :
.MSH|^~\&|MRI|ABC|||201403251406||QRY|173883426|P|2.1
QRD|201403251406|R|I|xxxxx|||25^RD|AB851656^|MPI
QRF|UPI||||
.
is from the client and
.MSH|^~\&|MRI|ABC|||201403251406||QRY|173883426|P|2.1
QRD|201403251406|R|I|xxxx|||25^RD|AB851656^|MPI
QRF|UPI||||
MSA|AA|173883426
.
is from the server. the response returned varies depending on the request and what is created after the business logic executes (but it is always going to be the same format- HL7 en(dot)wikipedia(dot)org/wiki/Health_Level_7 ). HL7 follows MLLP messaging format where each message begins with a Start Block code (0x0B) and each segment within the message is terminated with a Carriage Return code (0x0D) and each message is terminated by an End Block code (0x1C) followed by a Carriage Return code (0x0D). Once i get the request i have a business logic class that parses out the values, calls a web service gets the data and constructs a the tcp reply. What i would like to know is where in SuperSocket can i have a method or event listener to read the buffer and do my business logic and return the response for the same session. I know that there are concepts like filters and commands in SuperSocket but i haven't been able to figure them out. Any help is greatly appreciated. Let me know if you need additional detail.

" Message: Security error." While Requesting a Https Uri using WebClient OR HttpWebRequest using SilverLight Client

My Silverlight Client and REST Web Server(Implented using ASP.NET Handlers) both are on same domain.
Both HTTP and HTTPS protocol bindings are configured in IIS 7.0
When Request a URI using HTTPS , i Get Error " Message: "Security error."
But Same URI works just fine on HTTP request without any error
private void btnLoginWebRequest_Click(object sender, RoutedEventArgs e)
{
bool httpResult = WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);
bool httpsResult = WebRequest.RegisterPrefix("https://", WebRequestCreator.ClientHttp);
this.Dispatcher.BeginInvoke(()=>
{
WebClient webClient = new WebClient();
webClient.Headers["CustomHeader"] = String.Format("myHeaders={0}", "Value");
webClient.OpenReadCompleted += new OpenReadCompletedEventHandler(webClient_OpenReadCompleted);
webClient.OpenReadAsync(new Uri(#"https://xxx.xx.xxx.xxx/MyRESTApi/UserGroups"));
});
}
void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
if (e.Error == null)
{
}
}
I Get a Error and e.Error contains the following Error information
{System.Security.SecurityException: Security error.
at System.Net.Browser.ClientHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Net.WebClient.GetWebResponse(WebRequest request, IAsyncResult result)
at System.Net.WebClient.OpenReadAsyncCallback(IAsyncResult result)}
[System.Security.SecurityException]: {System.Security.SecurityException: Security error.
at System.Net.Browser.ClientHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Net.WebClient.GetWebResponse(WebRequest request, IAsyncResult result)
at System.Net.WebClient.OpenReadAsyncCallback(IAsyncResult result)}
Data: {System.Collections.ListDictionaryInternal}
InnerException: null
Message: "Security error."
StackTrace: " at System.Net.Browser.ClientHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)\r\n at System.Net.WebClient.GetWebResponse(WebRequest request, IAsyncResult result)\r\n at System.Net.WebClient.OpenReadAsyncCallback(IAsyncResult result)"
crossdomain.xml is as follows :-
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<site-control permitted-cross-domain-policies="all"/>
<allow-access-from domain="*" secure="true"/>
<allow-http-request-headers-from domain="*" headers="*" secure="true"/>
</cross-domain-policy>
clientaccesspolicy.xml is as follows :-
<?xml version="1.0" encoding="utf-8"?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers="*">
<domain uri="https://"/>
<domain uri="http://"/>
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
I Have seen many threads related to similar error on stack overflow but not able to resolve this issue by any of the solutions provided in those threads. Am i missing something?

MULE ESB : Binding multiple Web Services to one Client

I have a client which connects to a Web service to get some information. I have a requirement where I have to send the same information to multiple services using different ports. To solve this without modifying the client code I found MULE ESB, which is supposed to do exactly what I need.
I've found a guide where I could connect one client to one service using MULE ESB and one port, but I cant find a way to chain the services so they all listen to one port but have different themselves.
This is how it's supposed to look like:
UPDATE :
here is my current Mule Applications config :
<mule xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" xmlns:spring="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="CE-3.2.1" xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd ">
<flow name="flows1Flow1" doc:name="flows1Flow1">
<http:inbound-endpoint exchange-pattern="request-response" address="http://localhost:4433/miniwebservice" mimeType="text/xml" doc:name="HTTP"/>
<http:outbound-endpoint exchange-pattern="request-response" address="http://localhost:4434/miniwebservice?wsdl" mimeType="text/xml" doc:name="HTTP"/>
</flow>
</mule>
Here is the WebService :
Client :
package miniwebservice;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
public class TestWsClient
{
public static void main( final String[] args ) throws Throwable
{
String url = ( args.length > 0 ) ? args[0] : "http://localhost:4434/miniwebservice";
Service service = Service.create(
new URL( url + "?wsdl" ),
new QName( "http://miniwebservice/", "HalloWeltImplService" ) );
HalloWelt halloWelt = service.getPort( HalloWelt.class );
System.out.println( "\n" + halloWelt.hallo( args.length > 1 ? args[1] : "" ) );
}
}
Server :
package miniwebservice;
import javax.xml.ws.Endpoint;
public class TestWsServer
{
public static void main( final String[] args )
{
String url = ( args.length > 0 ) ? args[0] : "http://localhost:4434/miniwebservice";
Endpoint.publish( url, new HalloWeltImpl() );
}
}
InterfaceImpl :
package miniwebservice;
import javax.jws.WebService;
#WebService( endpointInterface="miniwebservice.HalloWelt" )
public class HalloWeltImpl implements HalloWelt
{
public String hallo( String wer )
{
return "Hallo " + wer;
}
}
interface :
package miniwebservice;
import javax.jws.*;
#WebService
public interface HalloWelt
{
public String hallo( #WebParam( name = "wer" ) String wer );
}
If I start the Server and the Mule aplication and try to reach http://localhost:4434/miniwebservice?wsdl ower http://localhost:4433/miniwebservice I get the folowing Exception in my Browser (FireFox 8.0) :
Couldn't create SOAP message due to exception: XML reader error: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,1]
Message: Content is not allowed in prolog.
I just started to work with Mule so I thouth that this would be enouth to get redirect mule to the Service to get the wsdl but its seems like its a bit complicatet.
Disclaimers:
This is not the final solution to the whole problem, which includes dispatching to several services and aggregating results, but a step in the right direction.
This is not representative of how web service proxying is done in Mule (which is way simpler) but a barebone approach to HTTP request routing so aggregation can be added.
Since you want to forward HTTP GET requests to the ?wsdl processor and HTTP POST SOAP request to the web service, you need to handle the target HTTP method and request URI propagation yourself:
<flow name="flows1Flow1">
<http:inbound-endpoint exchange-pattern="request-response"
address="http://localhost:4433/miniwebservice" />
<message-properties-transformer scope="outbound">
<add-message-property key="http.method" value="#[header:INBOUND:http.method]" />
</message-properties-transformer>
<logger level="INFO" category="ddo" />
<http:outbound-endpoint exchange-pattern="request-response"
address="http://localhost:4434#[header:INBOUND:http.request]" />
</flow>
(tested and validated with TestWsClient and TestWsServer)