我正在使用加拿大渔业和海洋局SOAP Web服务(https://tides.gc.ca/eng/info/WebServicesWLD和https://ws-shc.qc.dfo-mpo.gc.ca/predictions?wsdl)设置潮汐观测端点。它涉及到查看使用原始PHP的旧应用程序,并将其移植到Laravel中。 vanilla和Laravel版本都可以使用,但是由于某种原因,在Laravel中,如果没有请求超时,我不能将结果的最大大小设置为50-100以上,但是在旧应用程序中,它设置为1000。本地,结果有所不同,唯一的区别似乎是使用Laravel。
我在PHP操场上举了一些例子。示例1和示例2在PHP操场上的最大大小为1000,并且响应时间相等,这似乎表明Laravel可能是问题所在。
示例1-旧的应用程序代码: https://www.tehplayground.com/XYXERmL9kHmdTvLD
示例2-新的应用程序代码,但已精简为原始PHP,以确保不是我自己的代码成为问题 https://www.tehplayground.com/N2T3PTQSBfaWSQPh
Laravel中的实现,在不超时的情况下最大大小不能超过50-100,而且我不知道为什么或如何解决它。
示例3-Laravel代码:
我包括了我正在使用的完整Laravel控制器,因为在我从存储请求的文件之外,它不依赖任何内容,可以运行,并且可以用来确认它是否是问题,或者可能会发生什么。最后,我将文件的一些输出包含在存储中。
<?php
namespace Ctow\Http\Controllers;
use SoapClient;
use Illuminate\Support\Facades\Log;
use Illuminate\Contracts\Filesystem\FileNotFoundException;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class MarineTidalController extends Controller
{
// ... Abridge for brevity
/**
* Get the observations for a marine tidal region.
*
* @see https://tides.gc.ca/eng/info/WebServicesWLD
* @see https://ws-shc.qc.dfo-mpo.gc.ca/predictions?wsdl
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Foundation\Application|\Illuminate\Http\JsonResponse|\Illuminate\Http\Response
*/
public function regionObservations(Request $request)
{
$this->validate($request, [
'region_index' => 'required|integer',
'start_date' => 'required|string',
'end_date' => 'required|string',
]);
try {
$file = $this->getTidalRegions();
} catch (FileNotFoundException $ex) {
return response('File Not Found', 404);
}
$regionIndex = $request->get('region_index');
$region = json_decode($file)->regions[$regionIndex];
$startDate = $request->get('start_date');
$endDate = $request->get('end_date');
try {
$stations = $this->searchPredications($region, $startDate, $endDate);
} catch (\Exception $ex) {
return response('Service Unavailable', 503);
}
return response()->json([
'stations' => $stations
]);
}
/**
* Get the tidal regions from storage.
*
* @return string
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
private function getTidalRegions()
{
try {
return Storage::disk('local')->get('/Data/tidal-regions.json');
} catch (FileNotFoundException $ex) {
Log::error($ex);
throw $ex;
}
}
/**
* Perform the search for the marine tidal predications.
*
* @param $region
* @param $startDate
* @param $endDate
* @return mixed
* @throws \SoapFault
*/
private function searchPredications($region, $startDate, $endDate)
{
$wsdl = 'https://ws-shc.qc.dfo-mpo.gc.ca/predictions?wsdl';
$params = [
'hilo', // High and low water-levels (tides)
$region->min_latitude, // Geospatial boundary
$region->max_latitude,
$region->min_longitude,
$region->max_longitude,
0.0, // Depth min
0.0, // Depth max
$startDate, // Date min
$endDate, // Date max
1, // Start
// ISSUE in the old application size max is set to 1000 and response is
// prompt like the examples in PHP playground, but can't get higher than
// 50-100 without timing out in Laravel, which greatly decreases the result
// set. Both these examples work using a size max of 1000, but when used
// in Laravel the response timesout.
//
// Example fiddle using old code:
// https://www.tehplayground.com/XYXERmL9kHmdTvLD
//
// Example fiddle using paired down code from this class in Laravel:
// https://www.tehplayground.com/N2T3PTQSBfaWSQPh
50, // Size max
true, // Metadata
'', // Specific fields in result (CSV)
'asc' // Sort order
];
try {
$client = new SoapClient($wsdl);
return $client->search(...$params);
} catch (\Exception $ex) {
Log::error($ex);
throw $ex;
}
}
}
从getTidalRegions
返回的数据示例,如果有人愿意测试控制器,则可以直接从getTidalRegions
返回该数据,并替换来自Storage的请求。
[
[
"region_name" => "Vancouver Island",
"min_latitude" => 48.195,
"max_latitude" => 51.048,
"min_longitude" => -128.54,
"max_longitude" => -122.728
],
[
"region_name" => "Prince Edward Island",
"min_latitude" => 45.622,
"max_latitude" => 47.122,
"min_longitude" => -65.544,
"max_longitude" => -59.634
],
[
"region_name" => "Newfoundland",
"min_latitude" => 46.559,
"max_latitude" => 52.052,
"min_longitude" => -59.502,
"max_longitude" => -52.427
],
[
"region_name" => "Nova Scotia",
"min_latitude" => 43.533,
"max_latitude" => 46.012,
"min_longitude" => -66.473,
"max_longitude" => -60.546
],
[
"region_name" => "Quebec",
"min_latitude" => 46.21,
"max_latitude" => 50.149,
"min_longitude" => -72.949,
"max_longitude" => -66.819
],
[
"region_name" => "Anticosti Island",
"min_latitude" => 47.115,
"max_latitude" => 50.444,
"min_longitude" => -66.742,
"max_longitude" => -60.875
]
]