با سلام خدمت دوستان عزیز
من دارم از یک سرویس مربوط به یک سامانه مرکز تماس استفاده می کنم
به شکلی که ابتدا توی یک پروژه Asp.net core Web API توی یک کنترلر از اون سرویس استفاده می کنم و با استفاده از WebClient یک ریکوست میزنم و در پاسخ یک مقداری که مربوط به فایل صوتی هست رو دریافت می کنم
ریزالت دریافتی به این شکله :
من متوجه شدم این سامانه مرکز تماس فایل صوتی رو به صورت باینری در دیتابیس ذخیره میکنه
به دلایل امنیتی من مجبورم از این سرویس، سمت سرور با asp.net core استفاده کنم و از همین پروژه asp به عنوان وب سرویس استفاده کرده و ریسپانس ( یعنی همون مقادیر باینری) رو به سمت کلاینت به صورت rest api ارسال کنم.
کاری که من کردم اینه :
سمت سرور با استفاده از WebClient ریکویت ارسال می کنم و مقدار دریافتی رو ریترن میکنم تا کلاینت ازش استفاده کنه:
string Response = string.Empty;
string url = "http://172.10.18.15/api/v4/reports/audio/download";
var obj = new
{
file = "20230627_v2.16879661.113359.mp3"
};
var json = JsonConvert.SerializeObject(obj);
var client = new WebClient();
client.Headers.Add("Content-Type", "application/json");
client.Headers.Add("X-APIKEY", "knVUCPr42ryVoPCpKgDgKcDkKjilG36u...");
Response = client.UploadString(url, "POST", json);
return Ok(Response);
ریسپانس رو بدون مشکل به همون شکل باینری دریافت می کنم و اون رو سمت کلاینت به صورت res api استفاده می کنم به این شکل:
axios.get("https://localhost:5001/api/SimotelEvent/NewState/aaa").then(res=>{
console.log(res);
const blob = new Blob([res.data], {
type:"audio/mp3"
})
const url = URL.createObjectURL(blob)
new Audio(url).play()
});
ریسپانس بدون مشکل برمیگرده ولی نمیشه ازش به صورت Audio استفاده کرد .
از این کد هم سمت کلاین استفاده کردم دیگه ارور نداد ولی نتیجه چیزی نبود:
fetch("https://localhost:5001/api/SimotelEvent/NewState/aaa")
.then((response) => {
console.log(response);
return response.blob()
})
.then((myBlob) => {
const objectURL = URL.createObjectURL(new Blob([myBlob], {type: "audio/mp3"}));
console.log(objectURL);
new Audio(objectURL)
var audio = document.getElementById('audio');
var source = document.getElementById('audioSource');
source.src = objectURL;
});
حالا اگر دوستان در مورد اینکه فایل صوتی رو سمت کلاینت استفاده کنم و یا اصلا همون سمت سرور ذخیرش کنم راهنمایی بفرمایند ممنون میشم
سلام خوبی ببین راستش فک کنم اره مشکل شما در تبدیل رشته بازگشتی از سرور به فایل صوتی هستش این راهی که میگم رو برو ببین حل میشه یا خیر
سمت سرور:
به جای بازگشت رشته باینری، فایل صوتی را بصورت باینری خام (byte array) به سمت کلاینت ارسال کن برای این کارهم میتونی از نوع دادهای byte[]
در جایگزینی string
استفاده کنی
در صورتی که فایل صوتی را به فرمت MP3 دریافت میکنی هدر Content-Type
را به "audio/mpeg"
تغییر بده
قبل از ارسال فایل صوتی، هدر Content-Length
را با طول فایل صوتی پر کنی
به علاوه، هدرهای دیگریمثل "Accept-Ranges: bytes"
و "Cache-Control: no-cache"
نیز برای بهبود عملکرد پخش فایل صوتی درمرورگر میتوانید اضافه کننی
الان باید سمت سرور این جوری باشه
byte[] Response;
string url = "http://172.10.18.15/api/v4/reports/audio/download";
var obj = new
{
file = "20230627_v2.16879661.113359.mp3"
};
var json = JsonConvert.SerializeObject(obj);
var client = new WebClient();
client.Headers.Add("Content-Type", "audio/mpeg"); // تغییر Content-Type
client.Headers.Add("X-APIKEY", "knVUCPr42ryVoPCpKgDgKcDkKjilG36u...");
Response = client.UploadData(url, "POST", Encoding.Default.GetBytes(json)); // ارسال رشته به عنوان بایتها و استفاده از UploadData
// تنظیم هدر Content-Length
HttpContext.Response.ContentLength = Response.Length;
// تنظیم هدر Accept-Ranges
HttpContext.Response.Headers.Add("Accept-Ranges", "bytes");
// تنظیم هدر Cache-Control
HttpContext.Response.Headers.Add("Cache-Control", "no-cache");
return File(Response, "audio/mpeg"); // بازگشت فایل صوتی به عنوان نتیجه
سمت کلاینت:
با این تغییرات می تونی فایل صوتی رو به عنوان یک Blob
دریافت کنی و اونو را برای پخش استفاده کنی کد کلاینت باید اینجوری باشه
fetch("https://localhost:5001/api/SimotelEvent/NewState/aaa")
.then((response) => {
return response.blob();
})
.then((myBlob) => {
const objectURL = URL.createObjectURL(myBlob);
new Audio(objectURL).play();
});
سلام خوبی ببین فک کنم مشکلی که داری نحوه ااستفاده از fetch یا Audio باشه که توی کدت کاملا مشخصه
برای اینکه یه فایل صوتی رو با استفاده از ریسپانسی که از سرور دریافت کردی نمایش بدی از این کد استفاده کن
fetch("https://localhost:5001/api/SimotelEvent/NewState/aaa")
.then(response => response.arrayBuffer())
.then(data => {
const audioContext = new (window.AudioContext || window.webkitAudioContext)();
return audioContext.decodeAudioData(data);
})
.then(audioBuffer => {
const audioSource = audioContext.createBufferSource();
audioSource.buffer = audioBuffer;
audioSource.connect(audioContext.destination);
audioSource.start(0);
});
اگر باز هم مشکلی وجود داشت، لطفاً ارورهایی که در کنسول مرورگر دریافت میکنی رو به اشتراک بزار تا بتونیم بهتر کمکت کنیم.
@Arshiamohammadei
مهندس جان سلام و تشکر بابت وقتی که گذاشتید
کد شما رو استفاده کردم و توی این خط کد این ارور رو دارم
یه نکته هم بگم:
سرویس اصلی داره سمت سرور استفاده میشه و درواقع فایل صوتی داره به همون شکل باینری سمت سرور از API اصلی دریافت میشه و ظاهرا به صورت یک استرینگ به سمت کلاینت ارسال میشه.
https://localhost:5001/api/SimotelEvent/NewState/aaa این url مربوط به سرویسیه که من خودم ساختم تا مقدار دریافتی رو بشه سمت کلاینت استفاده کرد.
مقداری که سمت سرور داره دریافت میشه از سرویس اصلی به این شکله:
حالا نمیدونم این نکته تاثیری در این مشکل داره یا نه
درواقع من دارم یک رشته به سمت کلاینت ارسال می کنم
حالا نمیدونم سمت سرور آیا باید چیزی ست کنم که سمت کلاینت به صورت یک فایل صوتی شناخته بشه
سلام خوبی ببین راستش فک کنم اره مشکل شما در تبدیل رشته بازگشتی از سرور به فایل صوتی هستش این راهی که میگم رو برو ببین حل میشه یا خیر
سمت سرور:
به جای بازگشت رشته باینری، فایل صوتی را بصورت باینری خام (byte array) به سمت کلاینت ارسال کن برای این کارهم میتونی از نوع دادهای byte[]
در جایگزینی string
استفاده کنی
در صورتی که فایل صوتی را به فرمت MP3 دریافت میکنی هدر Content-Type
را به "audio/mpeg"
تغییر بده
قبل از ارسال فایل صوتی، هدر Content-Length
را با طول فایل صوتی پر کنی
به علاوه، هدرهای دیگریمثل "Accept-Ranges: bytes"
و "Cache-Control: no-cache"
نیز برای بهبود عملکرد پخش فایل صوتی درمرورگر میتوانید اضافه کننی
الان باید سمت سرور این جوری باشه
byte[] Response;
string url = "http://172.10.18.15/api/v4/reports/audio/download";
var obj = new
{
file = "20230627_v2.16879661.113359.mp3"
};
var json = JsonConvert.SerializeObject(obj);
var client = new WebClient();
client.Headers.Add("Content-Type", "audio/mpeg"); // تغییر Content-Type
client.Headers.Add("X-APIKEY", "knVUCPr42ryVoPCpKgDgKcDkKjilG36u...");
Response = client.UploadData(url, "POST", Encoding.Default.GetBytes(json)); // ارسال رشته به عنوان بایتها و استفاده از UploadData
// تنظیم هدر Content-Length
HttpContext.Response.ContentLength = Response.Length;
// تنظیم هدر Accept-Ranges
HttpContext.Response.Headers.Add("Accept-Ranges", "bytes");
// تنظیم هدر Cache-Control
HttpContext.Response.Headers.Add("Cache-Control", "no-cache");
return File(Response, "audio/mpeg"); // بازگشت فایل صوتی به عنوان نتیجه
سمت کلاینت:
با این تغییرات می تونی فایل صوتی رو به عنوان یک Blob
دریافت کنی و اونو را برای پخش استفاده کنی کد کلاینت باید اینجوری باشه
fetch("https://localhost:5001/api/SimotelEvent/NewState/aaa")
.then((response) => {
return response.blob();
})
.then((myBlob) => {
const objectURL = URL.createObjectURL(myBlob);
new Audio(objectURL).play();
});
@Arshiamohammadei
مهندس با تمام وجود ازتون ممنونم
مشکل با کدی که سمت سرور برام نوشتید حل شد.
توی راکت معمولا مسلط به لاراول هستن. من فکر نمیکردم اینجا کسی باشه که بتونه جوابمو بده
مشخصه که شما به سی شارپ مسلط هستید.
@Arshiamohammadei
مهندس یه سوال دیگه در مورد جایگزین کردن HttpClient بجای WebClient میخوام بپرسم و ازتون خواهش میکنم اگه میشه اونجا هم پاسخ بدید. اونجا توی اون سوال تگتون میکنم.
@Arshiamohammadei
مهندس میشه خواهش کنم همین کد بک اند رو با HttpClient هم بنویسید
خودم که انجام میدم ارور 415 unsupported media type دارم.
چشم وایسا
اینو توی وب کلاینتت قرار بده:
using System.Net.Http;
using System.Text;
// ...
string url = "http://172.10.18.15/api/v4/reports/audio/download";
var obj = new
{
file = "20230627_v2.16879661.113359.mp3"
};
var json = JsonConvert.SerializeObject(obj);
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("X-APIKEY", "knVUCPr42ryVoPCpKgDgKcDkKjilG36u...");
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync(url, content);
var bytes = await response.Content.ReadAsByteArrayAsync();
// تنظیم هدر Content-Length
HttpContext.Response.ContentLength = bytes.Length;
// تنظیم هدر Accept-Ranges
HttpContext.Response.Headers.Add("Accept-Ranges", "bytes");
// تنظیم هدر Cache-Control
HttpContext.Response.Headers.Add("Cache-Control", "no-cache");
return File(bytes, "audio/mpeg");
}
@Arshiamohammadei
واقعا ممنونم از وقتی که میذارید. این لطف شما واقعا با ارزشه
مهندس جان نمیدونم چرا به این شکل (HttpClient) که استفاده می کنم بازم ارور 415 از سمت سرویس دهنده بر میگرده!!
آیا مایل به ارسال نوتیفیکیشن و اخبار از طرف راکت هستید ؟