Offline SignalR Chat - asp.net

I have an online chat room, which works fine. However I would like to be able to send messages to offline users. How can I modify the code below to implement this change?
I would like to change ConnectedUsers to AllUsers, but for offline users I don't have a ConnectionId.
ChatHub.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using catchme.bg.Data;
using catchme.bg.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
namespace catchme.bg
{
[Authorize]
public class ChatHub : Hub
{
private CatchmeContext _context { get; set; }
public ChatHub(CatchmeContext context)
{
_context = context;
}
#region Data Members
static List<UserDetail> ConnectedUsers = new List<UserDetail>();
static List<MessageDetail> CurrentMessage = new List<MessageDetail>();
static List<PrivateMessageDetail> CurrentPrivateMessage = new List<PrivateMessageDetail>();
#endregion
#region Methods
public override async Task OnConnectedAsync()
{
var userName = Context.User.Identity.Name;
var id = Context.ConnectionId;
if (ConnectedUsers.Count(x => x.ConnectionId == id) == 0)
{
ConnectedUsers.Add(new UserDetail {ConnectionId = id, UserName = userName});
CurrentMessage.Clear();
CurrentPrivateMessage.Clear();
foreach (var user_name in ConnectedUsers.Select(u=>u.UserName).Distinct())
{
CurrentMessage.AddRange(GetMessageDetailsForUser(user_name).Result);
CurrentPrivateMessage.AddRange(GetPrivateMessageDetailsForUsers(Context.User.Identity.Name, user_name).Result);
}
// send to caller
await Clients.Caller.SendAsync("OnConnected", id, userName, ConnectedUsers, CurrentMessage, CurrentPrivateMessage);
// send to all except caller client
await Clients.AllExcept(id).SendAsync("NewUserConnected", id, userName, CurrentPrivateMessage);
}
}
public async Task SendMessageToAll(string message)
{
var userName = Context.User.Identity.Name;
// store last 100 messages in cache
AddMessageinCache(userName, message);
// Broad cast message
await Clients.All.SendAsync("MessageReceived", userName, message);
}
public async Task SendPrivateMessage(string toUserId, string message)
{
string fromUserId = Context.ConnectionId;
var toUser = ConnectedUsers.FirstOrDefault(x => x.ConnectionId == toUserId);
var fromUser = ConnectedUsers.FirstOrDefault(x => x.ConnectionId == fromUserId);
if (toUser != null && fromUser != null)
{
// send to
await Clients.Client(toUserId).SendAsync("SendPrivateMessage", fromUserId, fromUser.UserName, message);
// send to caller user
await Clients.Caller.SendAsync("SendPrivateMessage", toUserId, fromUser.UserName, message);
AddPrivateMessageinCache(fromUser.UserName, toUser.UserName, message);
}
}
public override async Task OnDisconnectedAsync(Exception ex)
{
var item = ConnectedUsers.FirstOrDefault(x => x.ConnectionId == Context.ConnectionId);
if (item != null)
{
ConnectedUsers.Remove(item);
var id = Context.ConnectionId;
await Clients.All.SendAsync("UserDisconnected", id, item.UserName);
}
}
#endregion
#region public Messages
private void AddMessageinCache(string userName, string message)
{
var publicMessage = new MessageDetail {UserName = userName, Message = message};
CurrentMessage.Add(publicMessage);
_context.MessageDetails.Add(publicMessage);
_context.SaveChanges();
if (CurrentMessage.Count > 100)
{
CurrentMessage.RemoveAt(0);
_context.MessageDetails.Remove(CurrentMessage[0]);
_context.SaveChanges();
}
}
#endregion
#region private Messages
private void AddPrivateMessageinCache(string userFrom, string userTo, string message)
{
var privateMessage = new PrivateMessageDetail { UserNameFrom = userFrom, UserNameTo = userTo, Message = message };
CurrentPrivateMessage.Add(privateMessage);
_context.PrivateMessageDetails.Add(privateMessage);
_context.SaveChanges();
var singleUserPrivateMessages = CurrentPrivateMessage.Where(u => u.UserNameFrom == userFrom && u.UserNameTo == userTo).ToList();
if (singleUserPrivateMessages.Count > 100)
{
CurrentPrivateMessage.Remove(singleUserPrivateMessages.First());
_context.PrivateMessageDetails.Remove(singleUserPrivateMessages.First());
_context.SaveChanges();
}
}
#endregion
public async Task<List<MessageDetail>> GetMessageDetailsForUser(string userName)
{
return await _context.MessageDetails.Where(u=>u.UserName==userName).ToListAsync();
}
public async Task<List<PrivateMessageDetail>> GetPrivateMessageDetailsForUsers(string userFrom, string userTo)
{
return await _context.PrivateMessageDetails.Where(u => u.UserNameFrom == userFrom && u.UserNameTo== userTo).ToListAsync();
}
}
}
Index.cshtml
#*<div>
<form id="send-form" action="#">
Send a message:
<input type="text" id="message-textbox" disabled/>
<button id="send-button" type="submit" disabled>Send</button>
</form>
<ul id="messages-list"></ul>
</div>
#section Scripts{
<script src="~/lib/signalr/signalr.min.js"></script>
<script src="~/js/chat.js"></script>
}*#
<link href="~/ChatStyle.css" rel="stylesheet" />
<link href="~/lib/jquery-ui/themes/base/jquery-ui.css" rel="stylesheet" />
#section Scripts{
#*<script src="~/lib/jquery-ui/ui/minified/core.js"></script>*#
<script src="~/lib/jquery-ui/jquery-ui.js"></script>
<script src="~/lib/jquery-ui/ui/minified/widget.js"></script>
<script src="~/lib/jquery-ui/ui/widgets/mouse.js"></script>
<script src="~/lib/jquery-ui/ui/widgets/draggable.js"></script>
<script src="~/lib/jquery-ui/ui/widgets/resizable.js"></script>
<script src="~/lib/signalr/signalr.min.js"></script>
<script src="~/js/chatjs.js"></script>
}
<div id="header">
Chat Room
</div>
<br />
<br />
<br />
<div id="divContainer">
#*<div id="divLogin" class="login">
<div>
Your Name:<br />
<input id="txtNickName" type="text" class="textBox" />
</div>
<div id="divButton">
<input id="btnStartChat" type="button" class="submitButton" value="Start Chat" />
</div>
</div>*#
<div id="divChat" class="chatRoom">
<div class="title">
Welcome to Chat Room [<span id='spanUser'></span>]
</div>
<div class="content">
<div id="divChatWindow" class="chatWindow">
</div>
<div id="divusers" class="users">
</div>
</div>
<div class="messageBar">
<input class="textbox" type="text" id="txtMessage" />
<input id="btnSendMsg" type="button" value="Send" class="submitButton" />
</div>
</div>
<input id="hdId" type="hidden" />
<input id="hdUserName" type="hidden" />
</div>
chatjs.js
$(function () {
setScreen(false);
var connection = new signalR.HubConnectionBuilder()
.withUrl("/hubs/chat")
.configureLogging(signalR.LogLevel.Information)
.build();
connection.start().catch(err => console.error(err.toString())).then(function () {
registerClientMethods(connection);
registerEvents(connection);
});
});
function setScreen(isLogin) {
if (!isLogin) {
$("#divChat").hide();
//$("#divLogin").show();
} else {
$("#divChat").show();
//$("#divLogin").hide();
}
}
function AddUser(connection, id, name, privateMessages) {
var userId = $('#hdId').val();
var code = "";
if (userId == id) {
code = $('<div class="loginUser">' + name + "</div>");
} else {
code = $('<a id="' + id + '" class="user" >' + name + '<a>');
$(code).dblclick(function () {
var id = $(this).attr('id');
if (userId != id)
OpenPrivateChatWindow(connection, id, name, privateMessages);
});
}
$("#divusers").append(code);
}
function AddMessage(userName, message) {
$('#divChatWindow').append('<div class="message"><span class="userName">' +
userName +
'</span>: ' +
message +
'</div>');
var height = $('#divChatWindow')[0].scrollHeight;
$('#divChatWindow').scrollTop(height);
}
function registerEvents(connection) {
$("#btnStartChat").click(function () {
var name = $("#txtNickName").val();
if (name.length > 0) {
connection.server.connect(name);
} else {
alert("Please enter name");
}
});
$('#btnSendMsg').click(function () {
var msg = $("#txtMessage").val();
if (msg.length > 0) {
//var userName = $('#hdUserName').val();
connection.send("SendMessageToAll", msg);
$("#txtMessage").val('');
}
});
$("#txtNickName").keypress(function (e) {
if (e.which == 13) {
$("#btnStartChat").click();
}
});
$("#txtMessage").keypress(function (e) {
if (e.which == 13) {
$('#btnSendMsg').click();
}
});
}
function registerClientMethods(connection) {
// Calls when user successfully logged in
connection.on("OnConnected",
function (id, userName, allUsers, messages, privateMessages) {
setScreen(true);
$('#hdId').val(id);
$('#hdUserName').val(userName);
$('#spanUser').html(userName);
// Add All Users
for (i = 0; i < allUsers.length; i++) {
AddUser(connection, allUsers[i].connectionId, allUsers[i].userName, privateMessages);
}
// Add Existing Public Messages
for (i = 0; i < messages.length; i++) {
AddMessage(messages[i].userName, messages[i].message);
}
// Add Existing Private Messages
for (i = 0; i < privateMessages.length; i++) {
AddMessage(privateMessages[i].userName, messages[i].message);
}
});
// On New User Connected
connection.on("NewUserConnected",
function (id, name, privateMesssages) {
AddUser(connection, id, name, privateMesssages);
});
// On User Disconnected
connection.on("UserDisconnected",
function (id, userName) {
$('#' + id).remove();
var ctrId = 'private_' + id;
$('#' + ctrId).remove();
var disc = $('<div class="disconnect">"' + userName + '" logged off.</div>');
$(disc).hide();
$('#divusers').prepend(disc);
$(disc).fadeIn(200).delay(2000).fadeOut(200);
});
connection.on("MessageReceived",
function (userName, message) {
AddMessage(userName, message);
});
connection.on("SendPrivateMessage",
function (windowId, fromUserName, message) {
var ctrId = 'private_' + windowId;
if ($('#' + ctrId).length == 0) {
createPrivateChatWindow(connection, windowId, ctrId, fromUserName);
}
$('#' + ctrId).find('#divMessage').append('<div class="message"><span class="userName">' +
fromUserName +
'</span>: ' +
message +
'</div>');
// set scrollbar
var height = $('#' + ctrId).find('#divMessage')[0].scrollHeight;
$('#' + ctrId).find('#divMessage').scrollTop(height);
});
}
function OpenPrivateChatWindow(connection, id, userName, privateMessages) {
var ctrId = 'private_' + id;
if ($('#' + ctrId).length > 0) return;
createPrivateChatWindow(connection, id, ctrId, userName);
//Add Private Messages
for (i = 0; i < privateMessages.length; i++) {
$('#' + ctrId).find('#divMessage').append('<div class="message"><span class="userName">' +
privateMessages[i].userNameFrom +
'</span>: ' +
privateMessages[i].message +
'</div>');
}
// set scrollbar
var height = $('#' + ctrId).find('#divMessage')[0].scrollHeight;
$('#' + ctrId).find('#divMessage').scrollTop(height);
}
function createPrivateChatWindow(connection, userId, ctrId, userName) {
var div = '<div id="' +
ctrId +
'" class="ui-widget-content draggable" rel="0">' +
'<div class="header">' +
'<div style="float:right;">' +
'<img id="imgDelete" style="cursor:pointer;" src="/images/delete.png"/>' +
'</div>' +
'<span class="selText" rel="0">' +
userName +
'</span>' +
'</div>' +
'<div id="divMessage" class="messageArea">' +
'</div>' +
'<div class="buttonBar">' +
'<input id="txtPrivateMessage" class="msgText" type="text" />' +
'<input id="btnSendMessage" class="submitButton button" type="button" value="Send" />' +
'</div>' +
'</div>';
var $div = $(div);
// DELETE BUTTON IMAGE
$div.find('#imgDelete').click(function () {
$('#' + ctrId).remove();
});
// Send Button event
$div.find("#btnSendMessage").click(function () {
$textBox = $div.find("#txtPrivateMessage");
var msg = $textBox.val();
if (msg.length > 0) {
connection.send("SendPrivateMessage", userId, msg);
$textBox.val('');
}
});
// Text Box event
$div.find("#txtPrivateMessage").keypress(function (e) {
if (e.which === 13) {
$div.find("#btnSendMessage").click();
}
});
AddDivToContainer($div);
}
function AddDivToContainer($div) {
$('#divContainer').prepend($div);
$div.draggable({
handle: ".header",
stop: function () {
}
});
////$div.resizable({
//// stop: function () {
//// }
////});
}

Please follow below stpes.
First In OnConnectedAsync(), take static list object and store user connectionId with
username.
you need to use OnDisconnectedAsync(). so whenever your any user get
offline, you will get call in this method and you can get connectionId in this method, find username from your list.
Now take one schema where you can manage, Pending to send message user List. add
useraname who is getting offline.
Now, When any user is connecting, first check whether that username is exist in
PendingToSendMessageUserList schema.
If yes, then first send him all pending message and then delete username from that
schema.
Hope you will understand, you need to implement it technically.

Related

Extract Data from Excel File to use it in an ASP.net core application

I am developing an application where I have to get the data from an Excel sheet and use it in the application, but I am having trouble accessing the data. Should I use Entity Framework and move the Data to a database or do I just import the data from Excel and use it?
Not sure what trouble you are meeting to access the data. But here is a sample about importing Excel data to Asp.net core application, you could refer to it.
In this sample, it will upload the excel file to the wwwroot folder using JavaScript first, then, using the DotNetCore.NPOI package (open source, you could install it via Nuget) to extract the data from excel. Details steps as below:
Suppose there have a testdata.xlsx file, the content as below:
Code in the controller:
private readonly IWebHostEnvironment _hostEnvironment;
public HomeController(ILogger<HomeController> logger, IWebHostEnvironment environment)
{
_logger = logger;
_hostEnvironment = environment;
}
public IActionResult Upload()
{
return View();
}
[HttpPost]
public IActionResult Import()
{
IFormFile file = Request.Form.Files[0];
string folderName = "UploadExcel";
string webRootPath = _hostEnvironment.WebRootPath;
string newPath = Path.Combine(webRootPath, folderName);
StringBuilder sb = new StringBuilder();
if (!Directory.Exists(newPath))
{
Directory.CreateDirectory(newPath);
}
if (file.Length > 0)
{
string sFileExtension = Path.GetExtension(file.FileName).ToLower();
ISheet sheet;
string fullPath = Path.Combine(newPath, file.FileName);
using (var stream = new FileStream(fullPath, FileMode.Create))
{
file.CopyTo(stream);
stream.Position = 0;
if (sFileExtension == ".xls")
{
HSSFWorkbook hssfwb = new HSSFWorkbook(stream); //This will read the Excel 97-2000 formats
sheet = hssfwb.GetSheetAt(0); //get first sheet from workbook
}
else
{
XSSFWorkbook hssfwb = new XSSFWorkbook(stream); //This will read 2007 Excel format
sheet = hssfwb.GetSheetAt(0); //get first sheet from workbook
}
IRow headerRow = sheet.GetRow(0); //Get Header Row
int cellCount = headerRow.LastCellNum;
sb.Append("<table class='table table-bordered'><tr>");
for (int j = 0; j < cellCount; j++)
{
NPOI.SS.UserModel.ICell cell = headerRow.GetCell(j);
if (cell == null || string.IsNullOrWhiteSpace(cell.ToString())) continue;
sb.Append("<th>" + cell.ToString() + "</th>");
}
sb.Append("</tr>");
sb.AppendLine("<tr>");
var emplist = new List<EmployeeViewModel>();
for (int i = (sheet.FirstRowNum + 1); i <= sheet.LastRowNum; i++) //Read Excel File
{
IRow row = sheet.GetRow(i);
if (row == null) continue;
if (row.Cells.All(d => d.CellType == CellType.Blank)) continue;
for (int j = row.FirstCellNum; j < cellCount; j++)
{
if (row.GetCell(j) != null)
sb.Append("<td>" + row.GetCell(j).ToString() + "</td>");
}
sb.AppendLine("</tr>");
EmployeeViewModel emp = new EmployeeViewModel() {
EmployeeID = Convert.ToInt32(row.Cells[0].ToString()),
EmployeeName = row.Cells[1].ToString(),
Age = Convert.ToInt32(row.Cells[2].ToString()),
Sex = row.Cells[3].ToString(),
Designation = row.Cells[4].ToString()
};
emplist.Add(emp);
}
var result = emplist;
sb.Append("</table>");
}
}
return this.Content(sb.ToString());
//return View("Upload");
}
Code in the Upload view:
<form asp-controller="Home" asp-action="Export">
<div class="container">
<div class="row">
<div class="col-md-4">
<input type="file" id="fileupload" name="files" class="form-control" />
</div>
<div class="col-md-3">
<input type="button" name="Upload" value="Upload" id="btnupload" class="btn btn-primary" />
Download
</div>
<div class="col-md-5">
<input type="submit" name="Export" value="Create and Export" id="btnExport"
class="btn btn-primary" asp-action="Export" />
</div>
</div>
<div class="clearfix"> </div>
<div class="row">
<div id="divPrint"></div>
</div>
</div>
</form>
And the Java Script code:
<script type="text/javascript">
$(function () {
$('#btnupload').on('click', function () {
var fileExtension = ['xls', 'xlsx'];
var filename = $('#fileupload').val();
if (filename.length == 0) {
alert("Please select a file.");
return false;
}
else {
var extension = filename.replace(/^.*\./, '');
if ($.inArray(extension, fileExtension) == -1) {
alert("Please select only excel files.");
return false;
}
}
var fdata = new FormData();
var fileUpload = $("#fileupload").get(0);
var files = fileUpload.files;
fdata.append(files[0].name, files[0]);
$.ajax({
type: "POST",
url: "/Home/Import",
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
data: fdata,
contentType: false,
processData: false,
success: function (response) {
if (response.length == 0)
alert('Some error occured while uploading');
else {
$('#divPrint').html(response);
}
},
error: function (e) {
$('#divPrint').html(e.responseText);
}
});
})
$('#btnExport').on('click', function () {
var fileExtension = ['xls', 'xlsx'];
var filename = $('#fileupload').val();
if (filename.length == 0) {
alert("Please select a file then Import");
return false;
}
});
});
</script>
The result like this:
You could also create a Employee model to store the data:
public class EmployeeViewModel
{
public int EmployeeID { get; set; }
public string EmployeeName { get; set; }
public int Age { get; set; }
public string Sex { get; set; }
public string Designation { get; set; }
}
Then, when loop through the excel rows, use the following code to get the Employee List:
var emplist = new List<EmployeeViewModel>();
for (int i = (sheet.FirstRowNum + 1); i <= sheet.LastRowNum; i++) //Read Excel File
{
IRow row = sheet.GetRow(i);
if (row == null) continue;
if (row.Cells.All(d => d.CellType == CellType.Blank)) continue;
for (int j = row.FirstCellNum; j < cellCount; j++)
{
if (row.GetCell(j) != null)
sb.Append("<td>" + row.GetCell(j).ToString() + "</td>");
}
sb.AppendLine("</tr>");
EmployeeViewModel emp = new EmployeeViewModel() {
EmployeeID = Convert.ToInt32(row.Cells[0].ToString()),
EmployeeName = row.Cells[1].ToString(),
Age = Convert.ToInt32(row.Cells[2].ToString()),
Sex = row.Cells[3].ToString(),
Designation = row.Cells[4].ToString()
};
emplist.Add(emp);
}
If the above sample doesn't achieve your requirement, please explain more details about what trouble are you having and what library you are using to upload the excel.
Reference:
Import and Export Excel file using NPOI
Import (Insert) Excel file data into Database ASP.Net Core MVC (using OLEDB library)

Upload fails to fail to when file too large

Im trying to catch an error when uploading a file that is too large.
At the server, the multipart section reader throws which I catch and return as an BadRequest (also tried InternalError) :
try
{
var section = await reader.ReadNextSectionAsync();
while (section != null)
{
...
}
}
catch (Exception ex)
{
return StatusCode((int)HttpStatusCode.BadRequest, ProblemFactory.Shared.BadRequestProblem("Could not upload file", ex.Message));
}
To upload, I have the following (using RestSharp currently, but same result with HttpClient via HttpClientFactory):
var request = new RestRequest(REQ_UPLOADFILE, Method.POST, DataFormat.Json);
var token = await _agentTokenService.GetToken();
AddTokenHeader(request, token.AccessToken);
request.AddFile("file", path);
request.AddParameter("externalFileType", fileType, ParameterType.GetOrPost);
request.AddParameter("subType", subType, ParameterType.GetOrPost);
var resp = await _client.ExecuteTaskAsync(request);
if (resp.IsSuccessful)
{
return JsonConvert.DeserializeObject<ExternalFileResponse>(resp.Content);
}
else
{
string reason = "unknown error";
//switch(resp.StatusCode)
//{
// case HttpStatusCode.???
//}
throw new Exception($"Could not upload file: {reason}");
}
The response from the post is status code 0 with a message:
The stream does not support concurrent IO read or write operations
The upload is running in a task so I guess it's something to do with that, but there is only a single download running and if the file is smaller it works without a problem.
I can only think that something in the response handling is fracking with this somehow.
Does anyone have a clue??
Thanks and Merry Christmas :)
PS: Im using Kestrel only - no IIS or nginx - with options thus:
.UseKestrel(options =>
{
options.AddServerHeader = false;
options.Limits.MaxRequestBodySize = 100 * 1024 * 1024; // 100 MB
})
UPDATE
I think I understand this better now.
The server is terminating the connection when reading the bytes form the stream.
The client, writing asyncly, continues for a little bit, but I then try to read the response - hence the error message.
UPDATE
HttpClient does actually respond a little differently - I get my badrequest and the message is that the stream was closed.
here is a simple way to loading large file use ASP.NET.
(1)downloand webupload from https://github.com/fex-team/webuploader
(2) webupload can upload large file to chunk file,crate a webform
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="../Javascript/jquery-1.9.1.min.js"></script>
<link href="../javascript/webuploader/webuploader.css" rel="stylesheet" />
<script src="../javascript/webuploader/webuploader.js"></script>
</head>
<body >
<form>
<br /><br />
<div id="uploader" class="wu-example">
<div class="btns">
<div id="picker" style="display:inline-block">Select a File</div>
<input id="ctlBtn" type="button" value="Upload" class="btn btn-primary" style="border-radius:0px; position:relative; top:-13px"/>
</div>
<div id="thelist" class="uploader-list"></div>
</div>
<script>
_extensions = '3gp,mp4,rmvb,mov,avi,m4v';
_mimeTypes = 'video/*,audio/*,application/*';
var GUID = WebUploader.Base.guid();//一个GUID
// alert(GUID);
uploader = WebUploader.create({
auto: false,
// swf path
swf: '../javascript/webuploader/Uploader.swf',
//server receive data
server: '_uploadVideo.aspx',
pick: {
id: '#picker',
label: 'Select a File',
innerHTML: 'Select a File',
multiple: false
},
fileNumLimit: 1,
fileSingleSizeLimit: 1024 * 1024 * 120,
accept: {
title: 'large file',
extensions: _extensions,
mimeTypes: _mimeTypes, // eg. image/*,
},
chunked: true,//split large into small file
chunkSize: 1024 * 1024 * 2, //every small file size,this is 2M
formData: {
guid: GUID,
types:"upload"
}
});
uploader.on('fileQueued', function (file) {
$("#thelist").append('<div id="' + file.id + '" class="item">' +
'<b class="info">' + file.name + '</b> ' +
'<p class="state">wait...</p>' + '</div>');
});
uploader.on('uploadSuccess', function (file, response) {
//merge small into a large file
$('#' + file.id).find('p.state').html('<font color=green>upload success</font>');
$.post('_uploadVideo.aspx', { guid: GUID, fileName: file.name, types: "merge" ,r:Math.random(),itemid:<%=Request.QueryString["itemid"]%> },
function (data) {
if (data == 1) {
alert("success");
}
else {
alert("fail");
}
});
});
uploader.on("error", function (type, handler) {
if (type == "Q_TYPE_DENIED") {
alert("format error");
} else if (type == "F_EXCEED_SIZE") {
alert("size too large");
}
});
uploader.on('uploadProgress', function (file, percentage) {
var $li = $('#' + file.id),
$percent = $li.find('.progress .progress-bar');
// stop re-upload
if (!$percent.length) {
$percent = $('<div class="progress progress-striped active">' +
'<div class="progress-bar" role="progressbar" style="width: 0%">' +
'</div>' +
'</div>').appendTo($li).find('.progress-bar');
}
$li.find('p.state').text('uploading');
$percent.css('width', percentage * 100 + '%');
});
$("#ctlBtn").click(
function () {
uploader.upload();
}
);
</script>
</form>
</body>
</html>
(3)create a asp.net webform page _uploadVideo.aspx
delete all content,the aspx should only has 1 line
<%# Page Language="C#" AutoEventWireup="true" CodeFile="_uploadVideo.aspx.cs" Inherits="Gallery.Gallery._uploadVideo" %>
(4)in code _uploadVideo.aspx.cs wirte code below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using System.Data.SqlClient;
namespace Gallery.Gallery
{
public partial class _uploadVideo : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (Request["types"] == "upload")
{
if (Request.Form.AllKeys.Any(m => m == "chunk"))
{
int year = DateTime.Now.Year;
//取得chunk和chunks
int chunk = Convert.ToInt32(Request["chunk"]);
int chunks = Convert.ToInt32(Request["chunks"]);
string folder = Server.MapPath("../uploads/video/"+year+"/" + Request["guid"] + "/");
string path = folder + chunk;
//建立临时传输文件夹 create teamplate folder
if (!Directory.Exists(Path.GetDirectoryName(folder)))
{
Directory.CreateDirectory(folder);
}
FileStream addFile = new FileStream(path, FileMode.Append, FileAccess.Write);
BinaryWriter AddWriter = new BinaryWriter(addFile);
//获得上传的分片数据流 get chunk
var file = Request.Files[0];
Stream stream = file.InputStream;
BinaryReader TempReader = new BinaryReader(stream);
//将上传的分片追加到临时文件末尾
AddWriter.Write(TempReader.ReadBytes((int)stream.Length));
//关闭BinaryReader文件阅读器
TempReader.Close();
stream.Close();
AddWriter.Close();
addFile.Close();
TempReader.Dispose();
stream.Dispose();
AddWriter.Dispose();
addFile.Dispose();
string f_ext = Path.GetExtension(file.FileName);
string _result = "{\"chunked\" :\"true\",\"hasError\" :\"false\",\"f_ext\" :\"" + f_ext + "\" }";
System.Web.HttpContext.Current.Response.Write(_result);
}
}
if (Request["types"] == "merge")
{
try
{
int year = DateTime.Now.Year;
var guid = Request["guid"];//GUID
var uploadDir = Server.MapPath("../uploads/video/" + year+"/");//Upload 文件夹
//建立临时传输文件夹
if (!Directory.Exists(Path.GetDirectoryName(uploadDir)))
{
Directory.CreateDirectory(uploadDir);
}
var dir = Path.Combine(uploadDir, guid);//临时文件夹
var ext = Path.GetExtension(Request["fileName"]);
var files = Directory.GetFiles(dir);//获得下面的所有文件
var name = Guid.NewGuid().ToString("N") + ext;
var finalPath = Path.Combine(uploadDir, name);//最终的文件名
var fs = new FileStream(finalPath, FileMode.Create);
foreach (var part in files.OrderBy(x => x.Length).ThenBy(x => x))//排一下序,保证从0-N Write
{
var bytes = System.IO.File.ReadAllBytes(part);
fs.Write(bytes, 0, bytes.Length);
bytes = null;
System.IO.File.Delete(part);//删除分块
}
fs.Flush();
fs.Close();
Directory.Delete(dir);//删除文件夹
//INSERT INTO DB finalPath
SqlParameter[] p = {
new SqlParameter("#videopath","../uploads/video/" + year+"/"+name)
};
string sql = #"update portal_photoes set videopath=#videopath where id=" + int.Parse(Request["itemid"]);
//you can exe SQL to into database
System.Web.HttpContext.Current.Response.Write("1");
}
catch (Exception ex)
{
System.Web.HttpContext.Current.Response.Write("0");
}
}
}
}
}

visualforce javascript remoting doesn't work properly

I'm trying to create some html elements as a reponse to a button click in my visualforce page, and i am using javascript remoting, but no matter what i do the page keeps refreshing after the button click.
my visualforce page:
<apex:page Controller="BpmIcountPayment">
<head>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.css"/>
</head>
<body>
<script>
function addProductRow(e) {
e.preventDefault();
var productId = $('select[id$=productsLov]').val();
Visualforce.remoting.Manager.invokeAction(
'{!$RemoteAction.BpmIcountPayment.getProductRowData}',
productId,
function(result, event) {
if (event.status) {
productRowHtml = '<div id="p-' + result.Id + '">';
productRowHtml += '<span>' + result.Description + '<span>';
productRowHtml += '<button class="plusButton">+</button><input type="number">1</input><button class="minusButton">-</button>';
if (result.Name == 'discount') {
productRowHtml += '<input classtype="number"></input><span>₪</span>';
};
productRowHtml += '<span>' + result.Price + '₪</span>';
$('div[id$=productRows]').append(productRowHtml);
} else if (event.type === 'exception') {
console.log(event.message + ' ' + event.where);
} else {
console.log('else ' + event.message);
}
}, {escape: true});
}
</script>
</body>
<apex:form >
<div>
<apex:selectList id="productsLov" value="{!productsTitle}" multiselect="false" size="1">
<apex:selectOptions value="{!ProductsLov}"></apex:selectOptions>
</apex:selectList>
<button id="addProductButton" onclick="addProductRow()" reRender="false">add product</button>
</div>
<div id="productsRows">
</div>
</apex:form>
</apex:page>
I even managed to print the result into the console, but it does so after refreshing the page.
my controller:
public class BpmIcountPayment{
private final Account account;
public String productsTitle {
get { return 'products'; }
set;
}
public List<Product2> productsList {
get { return productsList; }
set { productsList = value; }
}
public BpmIcountPayment() {
account = [SELECT Id, Name, Site FROM Account
WHERE Id = :ApexPages.currentPage().getParameters().get('id')];
}
public Account getAccount() {
return account;
}
#RemoteAction
public static Product2 getProductRowData(string productId) {
Product2 product = [SELECT Id, Name, Family, Price__c, Description
FROM Product2
WHERE Id = :productId];
return product;
}
public List<SelectOption> getProductsLov() {
List<SelectOption> products = new List<SelectOption>();
productsList = [SELECT Id, Name, Family, Price__c, Description
FROM Product2
WHERE (Family = 'ShopProduct')
OR (Family = 'CourseParent')
OR (Family = 'SFCourseProgram')];
for (Product2 currProduct : productsList) {
products.add(new SelectOption(currProduct.Id, currProduct.Name));
}
return products;
}}
I found the issue! It was just a case of defining the button type as "button" because the default was "submit" and that caused the page to re-render

Chat application using signalr as wcf service

i have done the chat application using signalr client and chatsever implemented as class. Now i want to implement chat server as wcf service.
<link rel="stylesheet" href="Styles/jquery-ui.css" />
<script src="Scripts/jquery-1.8.2.js"></script>
<script src="Scripts/jquery-ui.js"></script>
<script type="text/javascript" src="Scripts/jquery.dialogextend.1_0_1.js"></script>
<script type="text/javascript" src="Scripts/jquery.signalR.js"></script>
<script type="text/javascript" src="Scripts/jQuery.tmpl.js"></script>
<script type="text/javascript" src="signalr/hubs"></script>
<script id="new-online-contacts" type="text/x-jquery-tmpl">
<div>
<ul>
{{each messageRecipients}}
<li id="chatLink${messageRecipientId}">${messageRecipientName}</li>
{{/each}}
</ul>
</div>
</script>
<script id="new-chatroom-template" type="text/x-jquery-tmpl">
<div id="chatRoom${chatRoomId}" class="chatRoom">
<ul id="messages${chatRoomId}" class="chatMessages">
</ul>
<form id="sendmessage${chatRoomId}" action="#">
<input type="text" id="newmessage${chatRoomId}" class="chatNewMessage"/>
<div class="clear"></div>
<input type="button" id="chatsend${chatRoomId}" value="Send" class="chatSend" OnClick="javascript:SRChat.sendChatMessage('${chatRoomId}')" />
<input type="button" id="chatend${chatRoomId}" value="End Chat" class="chatSend" OnClick="javascript:SRChat.endChat('${chatRoomId}')" />
</form>
</div>
</script>
<script id="new-chat-header" type="text/x-jquery-tmpl">
<div id="chatRoomHeader${chatRoomId}">
{{each messageRecipients}}
{{if $index == 0}}
${messageRecipientName}
{{else}}
, ${messageRecipientName}
{{/if}}
{{/each}}
<div>
</script>
<script id="new-message-template" type="text/x-jquery-tmpl">
<li class="message" id="m-${chatMessageId}">
<strong>${displayPrefix}</strong>
{{html messageText}}
</li>
</script>
<script id="new-notify-message-template" type="text/x-jquery-tmpl">
<li class="message" id="m-${chatMessageId}">
<strong>{{html messageText}}</strong>
</li>
</script>
<script type="text/javascript">
//<![CDATA[
$(document).ready(function () {
SRChat.attachEvents();
});
SRChat = new function () {
var Username = GetParameterValues('Username');
function GetParameterValues(param) {
var url = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for (var i = 0; i < url.length; i++) {
var urlparam = url[i].split('=');
if (urlparam[0] == param) {
return urlparam[1];
}
}
}
var chatRooms = 0;
var numRand = Username;
var senderId = numRand;
var senderName = 'User :' + numRand;
var sRChatServer;
window.onbeforeunload = function () {
if (chatRooms > 0)
return "All chat instances will be ended!";
};
this.attachEvents = function () {
$("#userNameLabel").html(senderName);
if ($.connection != null) {
jQuery.support.cors = true;
$.connection.hub.url = 'signalr/hubs';
sRChatServer = $.connection.sRChatServer;
$.connection.hub.start({ transport: 'auto' }, function () {
sRChatServer.server.connect(senderId, senderName).fail(function (e) {
alert(e);
});
});
sRChatServer.client.initiateChatUI = function (chatRoom) {
var chatRoomDiv = $('#chatRoom' + chatRoom.chatRoomId);
if (($(chatRoomDiv).length > 0)) {
var chatRoomText = $('#newmessage' + chatRoom.chatRoomId);
var chatRoomSend = $('#chatsend' + chatRoom.chatRoomId);
var chatRoomEndChat = $('#chatend' + chatRoom.chatRoomId);
chatRoomText.show();
chatRoomSend.show();
chatRoomEndChat.show();
}
else {
var e = $('#new-chatroom-template').tmpl(chatRoom);
var c = $('#new-chat-header').tmpl(chatRoom);
chatRooms++;
//dialog options
var dialogOptions = {
"id": '#messages' + chatRoom.chatRoomId,
"title": c,
"width": 360,
"height": 365,
"modal": false,
"resizable": false,
"close": function () { javascript: SRChat.endChat('' + chatRoom.chatRoomId + ''); $(this).remove(); }
};
// dialog-extend options
var dialogExtendOptions = {
"close": true,
"maximize": false,
"minimize": true,
"dblclick": 'minimize',
"titlebar": 'transparent'
};
e.dialog(dialogOptions).dialogExtend(dialogExtendOptions);
$('#sendmessage' + chatRoom.chatRoomId).keypress(function (e) {
if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
$('#chatsend' + chatRoom.chatRoomId).click();
return false;
}
});
}
};
sRChatServer.client.updateChatUI = function (chatRoom) {
var chatRoomHeader = $('#chatRoomHeader' + chatRoom.chatRoomId);
var c = $('#new-chat-header').tmpl(chatRoom);
chatRoomHeader.html(c);
};
sRChatServer.client.receiveChatMessage = function (chatMessage, chatRoom) {
sRChatServer.client.initiateChatUI(chatRoom);
var chatRoom = $('#chatRoom' + chatMessage.conversationId);
var chatRoomMessages = $('#messages' + chatMessage.conversationId);
var e = $('#new-message-template').tmpl(chatMessage).appendTo(chatRoomMessages);
e[0].scrollIntoView();
chatRoom.scrollIntoView();
};
sRChatServer.client.receiveLeftChatMessage = function (chatMessage) {
var chatRoom = $('#chatRoom' + chatMessage.conversationId);
var chatRoomMessages = $('#messages' + chatMessage.conversationId);
var e = $('#new-notify-message-template').tmpl(chatMessage).appendTo(chatRoomMessages);
e[0].scrollIntoView();
chatRoom.scrollIntoView();
};
sRChatServer.client.receiveEndChatMessage = function (chatMessage) {
var chatRoom = $('#chatRoom' + chatMessage.conversationId);
var chatRoomMessages = $('#messages' + chatMessage.conversationId);
var chatRoomText = $('#newmessage' + chatMessage.conversationId);
var chatRoomSend = $('#chatsend' + chatMessage.conversationId);
var chatRoomEndChat = $('#chatend' + chatMessage.conversationId);
chatRooms--;
var e = $('#new-notify-message-template').tmpl(chatMessage).appendTo(chatRoomMessages);
chatRoomText.hide();
chatRoomSend.hide();
chatRoomEndChat.hide();
e[0].scrollIntoView();
chatRoom.scrollIntoView();
};
sRChatServer.client.onGetOnlineContacts = function (chatUsers) {
var e = $('#new-online-contacts').tmpl(chatUsers);
var chatLink = $('#chatLink' + senderId);
e.find("#chatLink" + senderId).remove();
$("#chatOnlineContacts").html("");
$("#chatOnlineContacts").html(e);
};
}
};
this.sendChatMessage = function (chatRoomId) {
var chatRoomNewMessage = $('#newmessage' + chatRoomId);
if (chatRoomNewMessage.val() == null || chatRoomNewMessage.val() == "")
return;
var chatMessage = {
senderId: senderId,
senderName: senderName,
conversationId: chatRoomId,
messageText: chatRoomNewMessage.val()
};
chatRoomNewMessage.val('');
chatRoomNewMessage.focus();
sRChatServer.server.sendChatMessage(chatMessage).fail(function (e) {
alert(e);
});
return false;
};
this.endChat = function (chatRoomId) {
var chatRoomNewMessage = $('#newmessage' + chatRoomId);
var chatMessage = {
senderId: senderId,
senderName: senderName,
conversationId: chatRoomId,
messageText: chatRoomNewMessage.val()
};
chatRoomNewMessage.val('');
chatRoomNewMessage.focus();
sRChatServer.server.endChat(chatMessage).fail(function (e) {
//alert(e);
});
};
this.initiateChat = function (toUserId, toUserName) {
if (sRChatServer == null) {
alert("Problem in connecting to Chat Server. Please Contact Administrator!");
return;
}
sRChatServer.server.initiateChat(senderId, senderName, toUserId, toUserName).fail(function (e) {
alert(e);
});
};
};
//]]>
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<div id="userNameLabel">
</div>
<br />
<br />
<div id="chatRooms">
</div>
<div id="chatOnlineContacts">
</div>
</div>
</form>
</body>
My server side code is
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading.Tasks;
using SignalR.Hubs;
namespace SRChat
{
[HubName("sRChatServer")]
public class SRChatServer:Hub
{
#region Private Variables
private static readonly ConcurrentDictionary<string, MessageRecipient> _chatUsers = new ConcurrentDictionary<string, MessageRecipient>(StringComparer.OrdinalIgnoreCase);
private static readonly ConcurrentDictionary<string, ChatRoom> _chatRooms = new ConcurrentDictionary<string, ChatRoom>(StringComparer.OrdinalIgnoreCase);
#endregion
#region Public Methods
public bool Connect(string userId, string userName)
{
try
{
if (string.IsNullOrEmpty(userId) | string.IsNullOrEmpty(userName))
{
return false;
}
if (GetChatUserByUserId(userId) == null)
{
AddUser(userId, userName);
}
else
{
ModifyUser(userId, userName);
}
SendOnlineContacts();
return true;
}
catch (Exception ex)
{
throw new InvalidOperationException("Problem in connecting to chat server!");
}
}
public override Task Disconnect()
{
try
{
DeleteUser(Context.ConnectionId);
return null;
}
catch (Exception ex)
{
throw new InvalidOperationException("Problem in disconnecting from chat server!");
}
}
public bool InitiateChat(string fromUserId, string fromUserName, string toUserId, string toUserName)
{
try
{
if (string.IsNullOrEmpty(fromUserId) || string.IsNullOrEmpty(fromUserName) || string.IsNullOrEmpty(toUserId) || string.IsNullOrEmpty(toUserName))
{
return false;
}
var fromUser = GetChatUserByUserId(fromUserId);
var toUser = GetChatUserByUserId(toUserId);
if (fromUser != null && toUser != null)
{
if (!CheckIfRoomExists(fromUser, toUser))
{
//Create New Chat Room
ChatRoom chatRoom = new ChatRoom();
chatRoom.chatRoomInitiatedBy = fromUser.messageRecipientId;
chatRoom.chatRoomInitiatedTo = toUser.messageRecipientId;
chatRoom.messageRecipients.Add(fromUser);
chatRoom.messageRecipients.Add(toUser);
//create and save blank message to get new conversation id
ChatMessage chatMessage = new ChatMessage();
chatMessage.messageText = "Chat Initiated";
chatMessage.senderId = fromUser.messageRecipientId;
chatMessage.senderName = fromUser.messageRecipientName;
fromUser.chatRoomIds.Add(chatRoom.chatRoomId);
toUser.chatRoomIds.Add(chatRoom.chatRoomId);
//Create SignalR Group for this chat room and add users connection to it
Groups.Add(fromUser.connectionId, chatRoom.chatRoomId);
Groups.Add(toUser.connectionId, chatRoom.chatRoomId);
//Add Chat room object to collection
if (_chatRooms.TryAdd(chatRoom.chatRoomId, chatRoom))
{
//Generate Client UI for this room
Clients[fromUser.connectionId].initiateChatUI(chatRoom);
}
}
}
return true;
}
catch (Exception ex)
{
throw new InvalidOperationException("Problem in starting chat!");
}
}
public bool EndChat(ChatMessage chatMessage)
{
try
{
ChatRoom chatRoom;
if (_chatRooms.TryGetValue(chatMessage.conversationId, out chatRoom))
{
if (_chatRooms[chatRoom.chatRoomId].chatRoomInitiatedBy == chatMessage.senderId)
{
chatMessage.messageText = string.Format("{0} left the chat. Chat Ended!", chatMessage.senderName);
if (_chatRooms.TryRemove(chatRoom.chatRoomId, out chatRoom))
{
Clients[chatRoom.chatRoomId].receiveEndChatMessage(chatMessage);
foreach (MessageRecipient messageReceipient in chatRoom.messageRecipients)
{
if (messageReceipient.chatRoomIds.Contains(chatRoom.chatRoomId))
{
messageReceipient.chatRoomIds.Remove(chatRoom.chatRoomId);
Groups.Remove(messageReceipient.connectionId, chatRoom.chatRoomId);
}
}
}
}
else
{
MessageRecipient messageRecipient = GetChatUserByUserId(chatMessage.senderId);
if (messageRecipient != null && messageRecipient.chatRoomIds.Contains(chatRoom.chatRoomId))
{
chatRoom.messageRecipients.Remove(messageRecipient);
messageRecipient.chatRoomIds.Remove(chatRoom.chatRoomId);
if (chatRoom.messageRecipients.Count < 2)
{
chatMessage.messageText = string.Format("{0} left the chat. Chat Ended!", chatMessage.senderName);
if (_chatRooms.TryRemove(chatRoom.chatRoomId, out chatRoom))
{
Clients[chatRoom.chatRoomId].receiveEndChatMessage(chatMessage);
foreach (MessageRecipient messageReceipient in chatRoom.messageRecipients)
{
if (messageReceipient.chatRoomIds.Contains(chatRoom.chatRoomId))
{
messageReceipient.chatRoomIds.Remove(chatRoom.chatRoomId);
Groups.Remove(messageReceipient.connectionId, chatRoom.chatRoomId);
}
}
}
}
else
{
chatMessage.messageText = string.Format("{0} left the chat.", chatMessage.senderName);
Groups.Remove(messageRecipient.connectionId, chatRoom.chatRoomId);
Clients[messageRecipient.connectionId].receiveEndChatMessage(chatMessage);
Clients[chatRoom.chatRoomId].receiveLeftChatMessage(chatMessage);
Clients[chatRoom.chatRoomId].updateChatUI(chatRoom);
}
}
}
}
else
{
throw new InvalidOperationException("Problem in ending chat!");
}
return true;
}
catch (Exception ex)
{
throw new InvalidOperationException("Problem in ending chat!");
}
}
public bool SendChatMessage(ChatMessage chatMessage)
{
try
{
ChatRoom chatRoom;
if (_chatRooms.TryGetValue(chatMessage.conversationId, out chatRoom))
{
chatMessage.chatMessageId = Guid.NewGuid().ToString();
chatMessage.timestamp = DateTime.Now;
Clients[chatMessage.conversationId].receiveChatMessage(chatMessage, chatRoom);
return true;
}
else
{
throw new InvalidOperationException("Problem in sending message!");
}
}
catch (Exception ex)
{
throw new InvalidOperationException("Problem in sending message!");
}
}
private bool SendOnlineContacts()
{
try
{
OnlineContacts onlineContacts = new OnlineContacts();
foreach (var item in _chatUsers)
{
onlineContacts.messageRecipients.Add(item.Value);
}
Clients.onGetOnlineContacts(onlineContacts);
return false;
}
catch (Exception ex)
{
throw new InvalidOperationException("Problem in getting contacts!");
}
}
#endregion
#region Private Methods
private Boolean CheckIfRoomExists(MessageRecipient fromUser, MessageRecipient toUser)
{
foreach (string chatRoomId in fromUser.chatRoomIds)
{
Int32 count = (from mr in _chatRooms[chatRoomId].messageRecipients
where mr.messageRecipientId == toUser.messageRecipientId
select mr).Count();
if (count > 0)
{
return true;
}
}
foreach (string chatRoomId in toUser.chatRoomIds)
{
Int32 count = (from mr in _chatRooms[chatRoomId].messageRecipients
where mr.messageRecipientId == fromUser.messageRecipientId
select mr).Count();
if (count > 0)
{
return true;
}
}
return false;
}
private MessageRecipient AddUser(string userId, string userName)
{
var user = new MessageRecipient();
user.messageRecipientId = userId;
user.messageRecipientName = userName;
user.connectionId = Context.ConnectionId;
_chatUsers[userId] = user;
return user;
}
private MessageRecipient ModifyUser(string userId, string userName)
{
var user = GetChatUserByUserId(userId);
user.messageRecipientName = userName;
user.connectionId = Context.ConnectionId;
_chatUsers[userId] = user;
return user;
}
private Boolean DeleteUser(string userId, string userName)
{
var user = GetChatUserByUserId(userId);
if (user != null && _chatUsers.ContainsKey(user.messageRecipientId))
{
MessageRecipient messageRecipient;
return _chatUsers.TryRemove(user.messageRecipientId, out messageRecipient);
}
return false;
}
private Boolean DeleteUser(string connectionId)
{
var returnValue = false;
var user = GetChatUserByConnectionId(connectionId);
if (user != null && _chatUsers.ContainsKey(user.messageRecipientId))
{
MessageRecipient messageRecipient;
returnValue = _chatUsers.TryRemove(user.messageRecipientId, out messageRecipient);
//remoave from all groups and chatrooms
foreach (string chatRoomId in messageRecipient.chatRoomIds)
{
_chatRooms[chatRoomId].messageRecipients.Remove(messageRecipient);
Groups.Remove(messageRecipient.connectionId, chatRoomId);
//notify user left chat
ChatMessage chatMessage = new ChatMessage();
chatMessage.conversationId = chatRoomId;
chatMessage.senderId = messageRecipient.messageRecipientId;
chatMessage.senderName = messageRecipient.messageRecipientName;
if (_chatRooms[chatRoomId].chatRoomInitiatedBy == messageRecipient.messageRecipientId)
{
chatMessage.messageText = string.Format("{0} left the chat. Chat Ended!", messageRecipient.messageRecipientName);
ChatRoom chatRoom;
if (_chatRooms.TryRemove(chatRoomId, out chatRoom))
{
foreach (MessageRecipient messageReceipient in chatRoom.messageRecipients)
{
if (messageReceipient.chatRoomIds.Contains(chatRoomId))
{
messageReceipient.chatRoomIds.Remove(chatRoomId);
}
}
Clients[chatRoomId].receiveEndChatMessage(chatMessage);
}
}
else
{
if (_chatRooms[chatRoomId].messageRecipients.Count() < 2)
{
chatMessage.messageText = string.Format("{0} left the chat. Chat Ended!", messageRecipient.messageRecipientName);
ChatRoom chatRoom;
if (_chatRooms.TryRemove(chatRoomId, out chatRoom))
{
foreach (MessageRecipient messageReceipient in chatRoom.messageRecipients)
{
if (messageReceipient.chatRoomIds.Contains(chatRoomId))
{
messageReceipient.chatRoomIds.Remove(chatRoomId);
}
}
Clients[chatRoomId].receiveEndChatMessage(chatMessage);
}
}
else
{
chatMessage.messageText = string.Format("{0} left the chat.", messageRecipient.messageRecipientName);
Clients[chatRoomId].receiveLeftChatMessage(chatMessage);
}
}
}
}
return returnValue;
}
private MessageRecipient GetChatUserByUserId(string userId)
{
return _chatUsers.Values.FirstOrDefault(u => u.messageRecipientId == userId);
}
private MessageRecipient GetChatUserByConnectionId(string connectionId)
{
return _chatUsers.Values.FirstOrDefault(u => u.connectionId == connectionId);
}
#endregion
}
}
i want to implement this one as wcf service or web service. please help me in advance
I think the best way to achieve that is to create a windows managed service.(Cause you can't control the lifetime of your service when hosted in IIS with a per-call configuration).
So you should create a new windows service and host both your wcf service and signalr (it's only an idea but I think the code can looks like that):
public class HostWindowService : ServiceBase
{
public ServiceHost serviceHost = null;
public HostWindowService()
{
ServiceName = "WCFWindowsServiceSample";
}
public static void Main()
{
ServiceBase.Run(new HostWindowService());
}
protected override void OnStart(string[] args)
{
//host wcf service
if (serviceHost != null)
{
serviceHost.Close();
}
serviceHost = new ServiceHost(typeof(WCFService));
serviceHost.Open();
//host signalr
Task.Run(() => SignalRHost());
}
private void SignalRHost()
{
try
{
SignalR = WebApp.Start("http://localhost:8080");
}
catch (TargetInvocationException)
{
WriteToConsole("A server is already running at " + "http://localhost:8080");
return;
}
}
class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
app.MapSignalR();
}
}
protected override void OnStop()
{
if (serviceHost != null)
{
serviceHost.Close();
serviceHost = null;
}
}
}
References : How to: Host a WCF Service in a Managed Windows Service and Self-Hosting SignalR in a Windows Service

Client side event is not calling for " Clients.Group(groupName).MessageReceived(UserName, message, groupName); "

Hub class
public void sendToAll(string UserName,string message,string grpId,string groupName,string UserId)
{
if (grpId == "3")
{
//This is working
Clients.All.MessageReceived(UserName, message, groupName);
}
if (grpId == "4")
{ //This is not working
Clients.Group(groupName).MessageReceived(UserName,message,groupName);
}
}
Client side:
$('#btnSendToAll').click(function () {
var GrpId = $(this).parent().attr('groupid');
var GrpName = $(this).parent().attr('groupname1');
chat.server.sendToAll($("#hdnUserName").val(), $('#txtMsg').val(), GrpId, GrpName, $("#hdnUserId").val());
$('#dvGroupChat', $(this).parent()).find('ul').append($('#txtMsg').val());
$('#message').val('').focus();
});
chat.client.messageReceived = function (name, message, groupType) {
$('div[groupname1=' + groupType + ']').find('ul').append('<ul>' + name + ': ' + message + '');
};

Resources