I'm having great difficulty making a WSS Xsockets implementation. I've made a selfsigned certificate in IIS7. I've tried connecting several times via JS and it simply will not. What's more puzzling is that the non-secure implementation works absolutely fine.
My server code is as follows:
public class SSLConfig : ConfigurationSetting
{
public SSLConfig()
: base("wss://localhost:4509")
{
this.CertificateLocation = System.Security.Cryptography.X509Certificates.StoreLocation.LocalMachine;
this.CertificateSubjectDistinguishedName = "cn=localhost";
}
}
class Program
{
static void Main(string[] args)
{
var myCustomConfigs = new List<IConfigurationSetting>();
myCustomConfigs.Add(new SSLConfig());
using (var server = Composable.GetExport<IXSocketServerContainer>())
{
Console.WriteLine("running");
server.StartServers(configurationSettings: myCustomConfigs);
foreach (var serv in server.Servers)
{
Console.WriteLine(serv.ConfigurationSetting.Endpoint);
}
Console.ReadLine();
server.StopServers();
}
}
}
public class TestSockets : XSocketController
{
public TestSockets()
{
}
public void Echo(string message)
{
this.Send(new
{
Message = message
}.AsTextArgs("message"));
}
}
Javascript:
<html>
<head>
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="\scripts\XSockets.latest.js"></script>
<script>
var ws;
$(function () {
ws = new XSockets.WebSocket("wss://localhost:4509/TestSockets");
ws.on(XSockets.Events.open, function (clientInfo) {
alert(clientInfo);
console.log('Open', clientInfo);
});
ws.on(XSockets.Events.onError, function (err) {
alert(err);
console.log('Error', err);
});
$("#btnSocket").on("click", function () {
ws.publish("Echo", { message: XSockets.Utils.randomString(50) });
});
});
</script>
</head>
<body>
<input type="button" value="click" id="btnSocket"/>
</body>
</html>
It turns out that due to the use of a self signed certificate, Firefox threw an error when trying to establish a connection (Chrome simply kept silent...).
After visiting the URI with https:// instead of wss:// I was able to add exceptions on all browsers, and now I could connect to the wss server.
Related
I am getting the id which i have to delete but the last line of service.ts that is of delete method is not getting executed...
the files and code snippets I used are : -
COMPONENT.HTML
<li *ngFor="let source of sources$ | async | filter: filterTerm">
<div class="card">
<div class="card-body">
<h5 class="card-title">{{source.name}}</h5>
<p>URL:- <a href ='{{source.url}}'>{{source.url}}</a></p>
<a class="btn btn-primary" href='fetch/{{source.id}}' role="button">fetch</a>
<button class="btn btn-primary" (click)="deleteSource(source.id)">delete </button>
<br>
</div>
</div>
</li>
I tried to console the id geeting from html and the Id i am getting is correct.
//component.ts
export class SourcesComponent implements OnInit {
filterTerm!: string;
sources$ !: Observable<sources[]>;
// deletedSource !: sources;
constructor(private sourcesService: SourcesService) { }
// prepareDeleteSource(deleteSource: sources){
// this.deletedSource = deleteSource;
// }
ngOnInit(): void {
this.Source();
}
Source(){
this.sources$ = this.sourcesService.Sources()
}
deleteSource(id : string){
console.log(id)
this.sourcesService.deleteSource(id);
}
//service.ts
export class SourcesService {
API_URL = 'http://127.0.0.1:8000/sourceapi';
constructor(private http: HttpClient) { }
// let csrf = this._cookieService.get("csrftoken");
// if (typeof(csrf) === 'undefined') {
// csrf = '';
// }
/** GET sources from the server */
Sources() : Observable<sources[]> {
return this.http.get<sources[]>(this.API_URL,);
}
/** POST: add a new source to the server */
addSource(source : sources[]): Observable<sources[]>{
return this.http.post<sources[]> (this.API_URL, source);
//console.log(user);
}
deleteSource(id: string): Observable<number>{
let httpheaders=new HttpHeaders()
.set('Content-type','application/Json');
let options={
headers:httpheaders
};
console.log(id)
return this.http.delete<number>(this.API_URL +'/'+id)
}
}
Angular HTTP functions return cold observables. This means that this.http.delete<number>(this.API_URL +'/'+id) will return an observable, which will not do anything unless someone subscribes to it. So no HTTP call will be performed, since no one is watching the result.
If you do not want to use the result of this call, you have different options to trigger a subscription.
simply call subscribe on the observable:
deleteSource(id : string){
console.log(id)
this.sourcesService.deleteSource(id).subscribe();
}
Convert it to a promise and await it (or don't, if not needed) using lastValueFrom:
async deleteSource(id : string){
console.log(id)
await lastValueFrom(this.sourcesService.deleteSource(id));
}
I've built simple ErrorBoundary component for my project in Vue.js and I'm struggling to write unit test for it. Component's code below:
<template>
<div class="overvue-error-boundary">
<slot v-if="!error" />
<div class="error-message" v-else>Something went horribly wrong here.</div>
</div>
</template>
<script>
export default {
data () {
return {
error: false
}
},
errorCaptured (error, vm, info) {
this.error = true;
}
}
</script>
I've created an ErrorThrowingComponent that throws an error on created() lifecycle hook so I can test ErrorBoundary:
const ErrorThrowingComponent = Vue.component('error-throwing-component', {
created() {
throw new Error(`Generic error`);
},
render (h) {
return h('div', 'lorem ipsum')
}
});
describe('when component in slot throws an error', () => {
it('renders div.error-message', () => {
// this is when error is when 'Generic error' is thrown by ErrorThrowingComponent
const wrapper = shallowMount(OvervueErrorBoundary, {
slots: {
default: ErrorThrowingComponent
}});
// below code is not executed
expect(wrapper.contains(ErrorThrowingComponent)).to.be.false;
expect(wrapper.contains('div.error-message')).to.be.true;
});
});
The problem is that ErrorThrowingComponent throws an error when I'm trying to actually mount it (thus failing entire test). Is there any way I can prevent this from happening?
EDIT: What I'm trying to achieve is to actually mount the ErrorThrowing component in a default slot of ErrorBoundary component to assert if ErrorBoundary will render error message and not the slot. This is way I created the ErrorThrowingComponent in the first place. But I cannot assert ErrorBoundary's behavior, because I get an error when trying to create a wraper.
For anyone comming here with a similar problem: I've raised this on Vue Land's #vue-testing channel on Discord, and they suggested to move entire error-handling logic to a function which will be called from the errorCaptured() hook, and then just test this function. This approach seems sensible to me, so I decided to post it here.
Refactored ErrorBoundary component:
<template>
<div class="error-boundary">
<slot v-if="!error" />
<div class="error-message" v-else>Something went horribly wrong here. Error: {{ error.message }}</div>
</div>
</template>
<script>
export default {
data () {
return {
error: null
}
},
methods: {
interceptError(error) {
this.error = error;
}
},
errorCaptured (error, vm, info) {
this.interceptError(error);
}
}
</script>
Unit test using vue-test-utils:
describe('when interceptError method is called', () => {
it('renders div.error-message', () => {
const wrapper = shallowMount(OvervueErrorBoundary);
wrapper.vm.interceptError(new Error('Generic error'));
expect(wrapper.contains('div.error-message')).to.be.true;
});
});
I want to change my current text email format to HTML format, so that I can send an email in nicely formatted way with headers, font values etc as shown in the screenshot below.
Image showing email body with header font size etc
Currently I have text format for sending email using AWS.ses
exports.sendEmail = function(email, token, event, context) {
var ses = new AWS.SES({
region: process.env.SES_REGION
});
var eParams = {
Destination: {
ToAddresses: [email]
},
Message: {
Body: {
Text: {
//template or environment variable
Data: `Hello ${event.request.userAttributes.given_name},\n\nYour Device Validation Token is ${token}\nSimply copy this token and paste it into the device validation input field.`
}
},
Subject: {
//template or environment variable
Data: "CWDS - CARES Device Validation Token"
}
},
//environment variable
Source: process.env.SOURCE_EMAIL
};
/* eslint-disable no-unused-vars */
ses.sendEmail(eParams, function(err, data){
if(err) {
logWrapper.logExceptOnTest("FAILURE SENDING EMAIL - Device Verify OTP");
logWrapper.logExceptOnTest(event);
logWrapper.logExceptOnTest(context);
context.fail(err);
}
else {
logWrapper.logExceptOnTest("Device Verify OTP sent");
context.succeed(event);
}
});
/* eslint-enable no-unused-vars */
}
It's fairly straight forward, just add the Html section of the Body node, i.e.:
var eParams = {
Destination: {
ToAddresses: [email]
},
Message: {
Body: {
Text: {
Data: `Hello ${event.request.userAttributes.given_name},\n\nYour Device Validation Token is ${token}\nSimply copy this token and paste it into the device validation input field.`
},
Html: {
Data: `<html><head><title>Your Token</title><style>h1{color:#f00;}</style></head><body><h1>Hello ${event.request.userAttributes.given_name},</h1><div>Your Device Validation Token is ${token}<br/>Simply copy this token and paste it into the device validation input field.</div></body></html>`
}
},
Subject: {
//template or environment variable
Data: "CWDS - CARES Device Validation Token"
}
},
//environment variable
Source: process.env.SOURCE_EMAIL
};
However... I generally split out the email template into html and text files, and use handlebars to inject data items. Here is an extract of one of my working solutions:
contact/contact.js
var AWS = require('aws-sdk');
var ses = new AWS.SES();
var fs = require('fs');
var Handlebars = require('handlebars');
module.exports.sendemail = (event, context, callback) =>
var eventData = JSON.parse(event.body);
fs.readFile("./contact/emailtemplate.html", function (err, emailHtmlTemplate) {
if (err) {
console.log("Unable to load HTML Template");
throw err;
}
fs.readFile("./contact/emailtemplate.txt", function (err, emailTextTemplate) {
if (err) {
console.log("Unable to load TEXT Template");
throw err;
}
// Prepare data for template placeholders
var emailData = {
"given_name": event.request.userAttributes.given_name,
"token": token
};
// Inject data into templates
var templateTitle = Handlebars.compile(process.env.EMAIL_TITLE);
var titleText = templateTitle(emailData);
console.log(titleText);
emailData.title = titleText;
var templateText = Handlebars.compile(emailTextTemplate.toString());
var bodyText = templateText(emailData);
console.log(bodyText);
var templateHtml = Handlebars.compile(emailHtmlTemplate.toString());
var bodyHtml = templateHtml(emailData);
console.log(bodyHtml);
// Prepare SES params
var params = {
Destination: {
ToAddresses: [
process.env.EMAIL_TO
]
},
Message: {
Body: {
Text: {
Data: bodyText,
Charset: 'UTF-8'
},
Html: {
Data: bodyHtml
},
},
Subject: {
Data: titleText,
Charset: 'UTF-8'
}
},
Source: process.env.EMAIL_FROM
}
console.log(JSON.stringify(params,null,4));
// Send Email
ses.sendEmail(params, function(err,data){
if(err) {
console.log(err,err.stack); // error
var response = {
statusCode: 500,
headers: {
"Access-Control-Allow-Origin" : "*",
"Access-Control-Allow-Credentials" : true
},
body: JSON.stringify({"message":"Error: Unable to Send Message"})
}
callback(null, response);
}
else {
console.log(data); // success
var response = {
statusCode: 200,
headers: {
"Access-Control-Allow-Origin" : "*",
"Access-Control-Allow-Credentials" : true
},
body: JSON.stringify({"message":"Message Sent"})
}
callback(null, response);
}
});
}); //end of load text template
}); //end of load html template
};
contact/emailtemplate.html
<!DOCTYPE html>
<html>
<head>
<title>Your New Token</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style>
h1 { color:#f00; }
</style>
</head>
<body>
<div class="emailwrapper">
<div class="main">
<div class="content">
<h1>Hi {{given_name}}</h1>
<div style="padding:20px;">
<div>your new token is {{token}}.</div>
</div>
</div>
</div>
</div>
</body>
</html>
contact/emailtemplate.txt
Hi {{given_name}}
your new token is {{token}}.
Just trying to figure things out in Meteor JS. I am stuck trying to get a Meteor.call result object passed back into a template. Here is my code:
HTML Template
<template name="showTotals">
<div class="container">
{{#each recordCnt}}
{{/each}}
</div>
</template>
Client JS
//get a count per item
Template.showTotals.recordCnt = function(){
Meteor.call('getCounts', function(err, result) {
if (result) {
//console.log(result); <-this shows object in javascript console
return result;
}
else {
console.log("blaaaa");
}
});
}
Server JS
Meteor.startup(function () {
Meteor.methods({
getCounts: function() {
var pipeline = [{$group: {_id: null, count: {$sum : 1}}}];
count_results = MyCollection.aggregate(pipeline);
return count_results;
}
});
});
Global JS
MyCollection = new Meteor.Collection('folks');
I have tried adding a console.log(result) for the results of the call, and it displays in the javascript console with the expected results. I cannot get this to populate recordCnt however.
Any ideas?
You can't do it the way you want because the callback from the Meteor.call runs asynchronously.
You can, however, use the callback to set a Session value and have your helper read Session.get() instead.
Template.showTotals.rcdCount = function() {
return Session.get('rcdCount');
}
Template.showTotals.rendered = function() {
Meteor.call('getCounts', function(err, result) {
if (result) {
Session.set('rcdCount', result);
}
else {
console.log("blaaaa");
}
});
}
See here for a similar answer that includes an example of a "hacky" way of doing it.
I want to return just messageID but it doesn't work correctly. How can I return a single string value?
[WebMethod]
public string messageComeGetID(string from, string to)
{
try
{
sqlConn.Open();
}
catch (Exception e)
{
return null;
}
// select messageID from tblMessage where [from] = '2' AND [to] = '4' gibi.
SqlCommand cmd3 = new SqlCommand("select messageID from tblMessage where [from]=#from AND [to]=#to", sqlConn);
cmd3.Parameters.AddWithValue("#from", from);
cmd3.Parameters.AddWithValue("#to", to);
cmd3.Connection = sqlConn;
object value = cmd3.ExecuteScalar();
string messageID = Convert.ToString(value);
cmd3.ExecuteNonQuery();
cmd3.Dispose();
sqlConn.Close();
return messageID;
}
I can be implemented like this
WebService1.asmx
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Script.Serialization;
using System.Web.Script.Services;
using System.Web.Services;
namespace StackOverflow_Solve.Services
{
/// <summary>
/// Summary description for WebService1
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
[System.Web.Script.Services.ScriptService]
public class WebService1 : System.Web.Services.WebService
{
[WebMethod]
public string HelloWorld()
{
return "Hello World";
}
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string GetMessage() // Home.CS
{
//return "GOGO";
Context.Response.Output.Write("Hello World");
Context.Response.End();
return string.Empty;
}
}
}
full implementation is
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
<head> //HTML and Ajax
<title></title>
<script>
function GetMessage() {
//Load jQuery($) to Use
$(function() {
$.get("WebService1.asmx/GetMessage", function (data) {
console.log(data);
$("p").html(data);
});
});
}
</script>
</head>
<body>
<input type="button" onclick="GetMessage()" value="Get Message" />
<p></p>
</body>
</body>
</html>